題意
分析
乙個直觀的做法是,列舉前兩項,不斷檢查前一項,這需要維護乙個有序陣列並且帶下標(可以用乙個map>,將數字相同的數推倒乙個vector中,vector中存的就是相同的數的位置)
時間複雜度:o(n^2*(logn+logn))
這個做法不太行啊,兩個log,有點卡不過去
由於有很多重複的列舉,dp優化
dp[i][j]:以i,j為開始兩個的最大長度
轉移:顯然需要k且k>j的help, a[k]=a[i]+a[j] (k>j)即可(二分即可)
另一種dp[i][j]:以i,j為結束兩個的最大長度
轉移:需要k且k
但這個狀態不太好找二分不好check
時間複雜度o(n^2*logn)
#include #includeview code#include
#include
#include
#include
#include
#include
using
namespace
std;
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define dbg(x) cout<
#define pb push_back
#define fi first
#define se second
#define ll long long
#define sz(x) (int)(x).size()
#define pll pair#define pii pair#define pq priority_queuevector
v;int dp[1010][1010
];ll a[
1010
];int
main());
}if(n==1
) sort(v.begin(),v.end());
pll res;
int cnt=0
;
for(int i=n-1;i>=1;i--));
if(it!=v.end() && it->fi==a[i]+a[j])
else
if(dp[i][j]>cnt || (dp[i][j]==cnt && (pll)
cnt=dp[i][j];}}
}printf(
"%d\n
",cnt);
printf(
"%lld %lld
",res.fi,res.se);
for(int i=2;i)
printf("\n
");}
return0;
}
小D的劇場(思維dp)
時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 若你摘得小的星星 你將得到小的幸福 若你摘得大的星星 你將得到大的財富 若兩者都能摘得 你將得到永遠的願望 摘星是罪孽的寬恕 摘星是夜晚的奇蹟 抓住它吧 你所期望的...
CodeForces 1060D(思維 貪心)
n個人圍成乙個圈吃飯,每個人都要求自己的左右兩邊至少有多少座椅,求最少的座椅數量 第一次做這種題,看了好久沒有思路,仔細想一想,每次挑選左右座椅最大的那個加起來,最後得出的就是最小座椅數量。因為是乙個圈,選擇大的那一邊,下一次選擇就會把另一邊給覆蓋 include using namespace s...
codeforces 1375D 模擬 思維
1375d 1900的題 題意 給你乙個n,然後是乙個陣列,其中的值為0 n,定義mex為陣列中0 n不存在的最小的那個,操作為可以將第i個數字為mex,使得這個陣列為不遞減的陣列,可以證明操作次數在2n次內一定能實現,問你操作次數是多少,並輸出相對應的索引,操作次數不要求是最優的。思路 看到在2n...