标签:des style blog http color io os ar 使用
Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 279 Accepted Submission(s): 80
首先考虑解的结构一定是C1,C1,…,C1,C2,C3,…,Cm这种形式,其中满足C1<C2<C3<…<Cm
所以对a1,a2,a3,…,an去重后从小到大排序得到c1,c2,c3,…,cx其中x是sqrt(M)级别的,用DP[i][j]表示以ci和cj结尾的满足条件的最长序列
首先初值化 DP[i][i]=count(ci) 即ci在原序列中的个数。
而dp[i][j]=max(dp[k][i] 其中k≤i还满足ci−ck≤cj−ci)+1
这样的复杂度是 O(x^3),在题中x最大为1000级别所以会超时,要使用下面优化
因为 dp[i][j]=max(dp[k][i] 其中k≤i还满足ci−ck≤cj−ci)+1
dp[i][j+1]=max(dp[k][i] 其中k≤i还满足ci−ck≤cj+1−ci)+1
注意到cj+1>cj 所以满足ci−ck≤cj−ci的dp[k][i]必然满足ci−ck≤cj+1−ci因而不必重复计算
即最后复杂度可以为O(x^2).
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<set> #include<stack> #include<map> #include<ctime> #include<bitset> #define LL long long #define maxn (1<<22)+10 using namespace std; int cnt[maxn],c[2010],dp[2010][2010]; int main() { int i,n,m,j,k; int tmp,T,x,ans; cin >>T ; while(T--) { scanf("%d%d",&n,&m) ; memset(cnt,0,sizeof(cnt)); for( i = 1 ; i <= n ;i++) { scanf("%d",&x) ; cnt[x]++; } n = 0 ; memset(dp,0,sizeof(dp)); ans=0; for( i =0 ; i <= m ;i++)if(cnt[i]) { c[++n]=i; dp[n][n]=cnt[i]; ans=max(cnt[i],ans); } for( i = 1 ; i <= n ;i++) { tmp=dp[i][i]; k = i ; for( j = i+1 ; j <= n ;j++) { for( ; k >= 1 ;k--) { if(c[j]-c[i] >= c[i]-c[k]) tmp = max(tmp,dp[k][i]+1) ; else break ; } dp[i][j]=tmp; ans=max(ans,dp[i][j]); } } printf("%d\n",ans); } return 0 ; }
标签:des style blog http color io os ar 使用
原文地址:http://www.cnblogs.com/20120125llcai/p/4032336.html