1.HDU 1003
求最长连续相加的和。
dp[i]=max(a[i],dp[i-1]+a[i]);
dp[i]表示以 i 结尾的最大值。
再开/个strat去标记从哪里开始。
#include <iostream> #include<stdio.h> #include<string.h> using namespace std; int dp[100010]; int strat[100010]; int a[100010]; int main() { int t; scanf("%d",&t); int k=0; while(t--) { k++; int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } memset(dp,0,sizeof dp); memset(strat,0,sizeof dp); dp[0]=a[0]; strat[0]=0; int max=a[0]; int pp=0; for(int i=1;i<n;i++) { if(a[i]>a[i]+dp[i-1]) { dp[i]=a[i]; strat[i]=i; } else { dp[i]=dp[i-1]+a[i]; strat[i]=strat[i-1]; } if(max<dp[i]) { max=dp[i]; pp=i; } } printf("Case %d: ",k); printf("%d %d %d ",max,strat[pp]+1,pp+1); if(t) printf(" "); } return 0; }
2.hdu 1087
求最长上升序列的和;
dp[i]=max(dp[j])+a[i]; a[j]<a[i];
#include <iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[1005]; int a[1005]; int main() { int n; while(~scanf("%d",&n)) { if(n==0) break; for(int i=0;i<n;i++) { scanf("%d",&a[i]); } memset(dp,0,sizeof dp); dp[0]=a[0]; for(int i=1;i<n;i++) { int MAX=0; for(int j=0;j<i;j++) { if(a[i]>a[j]) { MAX=max(MAX,dp[j]); } } dp[i]=MAX+a[i]; } int t=0; for(int i=0;i<n;i++) { t=max(t,dp[i]); } cout<<t<<endl; } return 0; }
3.HDU 1159 最长公共子序列
dp[i][j]=dp[i-1][j-1]+1 a[i]==b[j]
dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
读入是0 开始。计数的时候 从1开始。
#include <iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[1005][1005]; char a[1005]; char b[1005]; int main() { while(cin>>a>>b) { int t1=strlen(a); int t2=strlen(b); memset(dp,0,sizeof dp); for(int i=1;i<=t1;i++) for(int j=1;j<=t2;j++) { if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } cout<<dp[t1][t2]<<endl; } return 0; }
4.hdu-1160
最长上升子序列加路径
DP[i]表示i结尾的最长数目;
自己加一个 0 0break 测试一下
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; struct node { int w; int v; int no; }mice[1000]; bool cmp(node a,node b) { if(a.w==b.w) return a.v<b.v;//最开始这里没有排一直出来5。因为体重一样的速度也在排。但是速度从小到大就不会被记录 return a.w<b.w; } int pre[1000]; int dp[1000]; int main() { int a,b; int k=0; while(cin>>a>>b) { mice[k].w=a; mice[k].v=b; mice[k].no=k+1; k++; } sort(mice,mice+k,cmp); memset(pre,-1,sizeof pre); for(int i=0;i<k;i++) { dp[i]=1; } int mx=0,p=-1; for(int i = 0; i < k; i++) { for(int j = 0; j < i; j++) { if( mice[j].v > mice[i].v) { if(dp[j]+1 > dp[i]) { dp[i] = dp[j]+1; pre[i] = j; } } } if(dp[i]>mx) { mx=dp[i]; p=i; } } cout<<mx<<endl; int res[10000]; int i=1; while(p!=-1) { res[i++]=mice[p].no; p=pre[p]; } i--; for(;i>=1;i--) cout<<res[i]<<endl; return 0; }
5.hdu-1176
这题详细写了。
dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]);
dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1]));
dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]);
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> using namespace std; int dp[11][100005];//i表示时间,j表示位子 int main() { int n; int t,p; while(~scanf("%d",&n)&&n) { int mx=0; memset(dp,0,sizeof dp); for(int i=0;i<n;i++) { scanf("%d%d",&p,&t); dp[p][t]++; mx=max(mx,t); } for(int i=mx-1;i>=0;i--) { dp[0][i]= dp[0][i]+max(dp[0][i+1],dp[1][i+1]); for(int j=1;j<10;j++) { dp[j][i]=dp[j][i]+max(dp[j-1][i+1],max(dp[j][i+1],dp[j+1][i+1])); } dp[10][i]= dp[10][i]+max(dp[10][i+1],dp[9][i+1]); } cout<<dp[5][0]<<endl; } return 0; }