DP LIS(最长上升子序列) POJ 2533 POJ 1836 POJ 2138 HDU 1069
O(NlogN):www.wutianqi.com/?p=1850
最长递增子序列
O(NlogN)算法:www.felix021.com/blog/read.php?1587
//POJ 2533 //最水的题 int main() { int n,i,j; int dp[1044],num[1044]; while(scanf("%d",&n)!=EOF){ memset(dp,0,sizeof(dp)); memset(num,0,sizeof(num)); for(i=0;i<n;i++){ scanf("%d",&num[i]); dp[i]=1; } for(i=0;i<n;i++){ for(j=0;j<i;j++){ if(num[i]>num[j]&&dp[i]<dp[j]+1) dp[i]=dp[j]+1; } } int ans=0; for(i=0;i<n;i++){ if(ans<dp[i]) ans=dp[i]; } printf("%d\n",ans); } return 0; }
//POJ 2533 //排成一队 凸的队伍。。低到高高到低 //计算要踢出几个人 int main() { int n,i,j; int dp1[1044],dp2[1004]; double num[1044]; while(scanf("%d",&n)!=EOF){ memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); memset(num,0,sizeof(num)); for(i=1;i<=n;i++){ scanf("%lf",&num[i]); dp1[i]=1; dp2[i]=1; } for(i=1;i<=n;i++){ for(j=1;j<i;j++){ if(num[i]>num[j]&&dp1[i]<dp1[j]+1) dp1[i]=dp1[j]+1; } } for(i=n;i>=1;i--){ for(j=n;j>i;j--){ if(num[i]>num[j]&&dp2[i]<dp2[j]+1) dp2[i]=dp2[j]+1; } } int t1,t2,ans=0;; for(int k=1;k<=n;k++){ t1=t2=0; for(i=1;i<=k;i++) if(t1<dp1[i]) t1=dp1[i]; for(i=k+1;i<=n;i++) if (t2<dp2[i]) t2=dp2[i]; if (ans<t1+t2) ans=t1+t2; } printf("%d\n",n-ans); } return 0; } /* 8 3 4 5 1 2 5 4 3 ans :2
//POJ 2138 //题意很清楚 int main() { int t,i,j,k,le,ans; char s[99]; int dp[1033]; while(scanf("%d",&t)!=EOF){ memset(l,0,sizeof(l)); scanf("%s",l[0].zi); l[0].len=strlen(l[0].zi); for(i=1;i<=t;i++){ scanf("%s",l[i].zi); l[i].len=strlen(l[i].zi); } memset(dp,0,sizeof(dp)); dp[0]=3; sort(l,l+t+1,cmp);//长度排序 for(i=1;i<=t;i++){ ans=0; for(j=0;j<i;j++){ if(l[j].len+1!=l[i].len) continue; le=0; for(k=0;k<l[i].len;k++){ if(l[i].zi[k]==l[j].zi[le]){//与上一个匹配 le++; } } if(le==l[j].len){//匹配成功 ans=dp[j]+1; } dp[i]=max(dp[i],ans); } } ans=0; for(i=0;i<=t;i++){ if(dp[i]>ans) ans=dp[i]; } for(i=t;i>=0;i--){ if(ans==dp[i]){ printf("%s\n",l[i].zi); break; } } } return 0; }
//HDU 1069 //叠箱子。下面的箱子长宽要大于上面的 bool cmp(node a,node b){ if(a.x==b.x) return a.y<b.y; return a.x<b.x; } int main() { node map[500]; int n,a,b,c,i,j,cas=1; while(scanf("%d",&n),n){ memset(map,0,sizeof(map)); for(i=0;i<n;i++){ scanf("%d%d%d",&a,&b,&c); map[i*6].x=a,map[i*6].y=b,map[i*6].z=c; map[i*6+1].x=a,map[i*6+1].y=c,map[i*6+1].z=b; map[i*6+2].x=b,map[i*6+2].y=a,map[i*6+2].z=c; map[i*6+3].x=b,map[i*6+3].y=c,map[i*6+3].z=a; map[i*6+4].x=c,map[i*6+4].y=b,map[i*6+4].z=a; map[i*6+5].x=c,map[i*6+5].y=a,map[i*6+5].z=b; } sort(map,map+6*n,cmp);// 长宽递增排序 int ans=0; for(i=0;i<n*6;i++){ int temp=0; for(j=0;j<i;j++){ if(map[i].x>map[j].x&&map[i].y>map[j].y) temp=big(temp,map[j].z); } map[i].z+=temp; //把小的箱子叠上去。 ans=max(ans,map[i].z); } printf("Case %d: maximum height = %d\n",cas++,ans); } }