#include<iostream>using namespace std;int a[100001];int main(){int T;int i,n,position1,end,thissum,maxsum,begin;cin>>T;for(int tt=1;tt<=T;tt++){cin>>n;for(i=0;i<n;i++)scanf("%d",&a[i]);position1=begin=end=0;maxsum=thissum=a[0];for(i=1;i<n;i++){if(thissum+a[i]<a[i])//如果当前值比a[i]小的话则改为a[i] {thissum=a[i];position1=i;//记录下改的位置 }else{thissum=thissum+a[i];}if(thissum>maxsum)//当前值比最大值大,则头尾都要改{maxsum=thissum;begin=position1;end=i;}}printf("Case %d:\n%d %d %d\n",tt,maxsum,begin+1,end+1); if(tt!=T){cout<<endl;}}system("pause");return 0;}
Common Subsequence
#include<iostream>#include<cstring>using namespace std;char str1[1001];char str2[1001];int dp[1001][1001];int main(){int i,j,max,len1,len2;while(cin>>str1>>str2){len1=strlen(str1);len2=strlen(str2);for(i=0;i<len1;i++){dp[i][0]=0;}for(i=0;i<len2;i++){dp[0][i]=0;}for(i=1;i<=len1;i++){for(j=1;j<=len2;j++){if(str1[i-1]==str2[j-1]){dp[i][j]=dp[i-1][j-1]+1;}else{dp[i][j]=dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];}}}cout<<dp[len1][len2]<<endl;}system("pause");return 0;}
FatMouse's Speed
/*首先按照关键字W升序进行排序,然后S[i]从1到i-1(是指外层循环中的第i个元素)开始遍历,找到w[i]>w[k],s[i]<s[k],使m[i]最大的位置,并记录。动态规划状态方程为:f[i] = max(f[k]+1,f[i]),1<=k<i;这里定义了一个struct mice 其中的len代表当前元素的状态长度,用来找到找到最长的,index用来记忆当前元素的真实下标,在排序后还能找到元素的下标。before用来找的当前元素的上一个元素的下标。*/#include <iostream>#include <stdlib.h>using namespace std;typedef struct{ int w,s; int len,index; int before;}mice;int cmp(const void *a,const void *b){ mice c = *(mice *)a; mice d = *(mice *)b; if(c.w==d.w) return d.s - c.s; else return c.w - d.w;}int main(){ mice m[10001]; int i = 1,flag,max=0,f[1001]; while(cin>>m[i].w>>m[i].s) { m[i].index = i; m[i].len=0; m[i].before=0; i++; } //cout<<i<<endl; qsort(m,i-1,sizeof(m[1]),cmp); for(int j = 1;j < i ;j++) { for(int k = 1; k< j;k++) { if(m[j].w>m[k].w&&m[j].s<m[k].s) { if(m[j].len<m[k].len+1) { m[j].len = m[k].len+1; m[j].before = k; if(m[j].len>=max) { max = m[j].len; flag = j; } } } } } cout<<max+1<<endl; f[1] = m[flag].index; i=2; while(m[flag].before!=0) { flag = m[flag].before; f[i] = m[flag].index; i++; } for(int j = i-1 ; j >=1 ; j--) { cout<<f[j]<<endl; } // for(int j = 1 ; j < i ;j++) // cout<<m[j].index<<" "<<m[j].w<<" "<<m[j].s<<endl; return 0;}
Humble Numbers
/*分析:用dp的思维解答 若一个数是Humble数,那么他的2、3、5、7倍仍然是Humble数。 定义a为第i个Humble数 a[n] = min( 2*a[m],3*a[n],5*a[k],7*a[l] ),m,n,k,l在被选择后彼此移动。 */#include <iostream>using namespace std;int main(){ int a[5843]={1},i,j,k,l,m,n,x[4],min; m = n = k = l = 1; for(i = 1;i < 5843;i++) { x[0]=a[m-1]*2; x[1]=a[n-1]*3; x[2]=a[k-1]*5; x[3]=a[l-1]*7; min = x[0]; if (x[1] < min) min = x[1]; if (x[2] < min) min = x[2]; if (x[3] < min) min = x[3]; a[i] = min; if(min == x[0]) m++; if(min == x[1]) n++; if(min == x[2]) k++; if(min == x[3]) l++; } while(cin >> n,n) { if(n % 10 == 1 && n % 100 != 11) printf("The %dst humble number is %d.\n",n,a[n-1]); else if(n % 10 == 2 && n % 100 != 12) printf("The %dnd humble number is %d.\n",n,a[n-1]); else if(n % 10 == 3 && n % 100 != 13) printf("The %drd humble number is %d.\n",n,a[n-1]); else printf("The %dth humble number is %d.\n",n,a[n-1]); } return 0;}
Monkey and Banana
/*类似于最长上升子序列,把箱子拆成3*n个,这样相当于把一个箱子分成高度不同的3个,按底面积从小到大排好,根据转移方程dp[i]=max{dp[j]}+c[i](1<=j<i&&a[i]>a[j]&&b[i]>b[j]),其中dp[i]表示前i个箱子能堆起的最大高度。*/#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct R{int a;int b;int c;int s;}r[200];bool cmp(R a,R b){return a.s<b.s;}int main(){int m=1,n,i,j,k,l,w,h,dp[200],temp,ans;while(scanf("%d",&n)!=-1&&n){ans=0;memset(dp,0,sizeof(dp));k=1;for(i=1;i<=n;i++){scanf("%d%d%d",&l,&w,&h);r[k].a=l;r[k].b=w;r[k].c=h;r[k].s=r[k].a*r[k].b;k++;r[k].a=w;r[k].b=l;r[k].c=h;r[k].s=r[k].a*r[k].b;k++;r[k].a=h;r[k].b=l;r[k].c=w;r[k].s=r[k].a*r[k].b;k++;r[k].a=h;r[k].b=w;r[k].c=l;r[k].s=r[k].a*r[k].b;k++;r[k].a=l;r[k].b=h;r[k].c=w;r[k].s=r[k].a*r[k].b;k++;r[k].a=w;r[k].b=h;r[k].c=l;r[k].s=r[k].a*r[k].b;k++;}sort(r+1,r+k,cmp);dp[1]=r[1].c;for(i=1;i<k;i++){temp=0;for(j=1;j<i;j++)if(r[i].a>r[j].a&&r[i].b>r[j].b&&temp<dp[j])temp=dp[j];dp[i]=temp+r[i].c;}for(i=1;i<k;i++)if(ans<dp[i])ans=dp[i];printf("Case %d: maximum height = %d\n",m++,ans);}return 0;}
数塔
/*此题采用动态规划自底向上计算,如果我们要知道所走之和最大,那么最后一步肯定是走最后一排数其中一个,向上退,倒数第二步肯定走最后一排数对应的倒数第二排最大的一个(将最后对应最后步走的最大的数加起来存在倒数第二步的数组中)再向上推,一直推到最上面的第0布,那么b[0][0]最后所存的结果一定是最大的*/#include<iostream>using namespace std;int main(){int T;int a[101][101];int dp[101][101];cin>>T;while(T--){int n;cin>>n;for(int i=0;i<n;i++){for(int j=0;j<=i;j++){cin>>a[i][j];}}dp[0][0]=0;for(int i=n-1;i>=0;i--){for(int j=i;j>=0;j--){if(i==n-1){dp[i][j]=a[i][j];}else{dp[i][j]=max(a[i][j]+dp[i+1][j],a[i][j]+dp[i+1][j+1]);}}}cout<<dp[0][0]<<endl;}system("pause");return 0;}
免费馅饼
#include<stdio.h>#include<cmath>#include<algorithm>using namespace std;int dp[100005][12];int main(){ int n,i,j,maxt; int x,t; while(scanf("%d",&n),n) { maxt=0; memset(dp,0,sizeof(dp)); for(i=0;i<n;i++) { scanf("%d%d",&x,&t); dp[t][x]++; if(maxt<t) maxt=t; } for(i=maxt-1;i>=0;i--) { dp[i][0]+=max(dp[i+1][1],dp[i+1][0]); for(j=1;j<11;j++) { dp[i][j]+=max(max(dp[i+1][j-1],dp[i+1][j]),dp[i+1][j+1]); } } printf("%d\n",dp[0][5]); } return 0; }
命运
/*设f[i][j]为走到(i,j)位置得到的最大权值。则f[i][j] = max {f[i-1][j],f[i][j-1],f[i][j*k](2<k <m/j)}+a[i][j]。再把f[i][j]初始化成-inf.f[1][1] =a[0][0].*/#include <iostream>#include <stdio.h>#include <string.h>using namespace std;int main(){ int c,n,m,a[21][1010],dp[21][1010],max; cin>>c; while(c--) { cin>>n>>m; memset(dp,0,sizeof(dp)); // max = -101 for(int i = 1 ; i <= n ; i++) { for(int j = 1 ; j <= m ; j++) { // cin>>a[i][j]; scanf("%d",&a[i][j]); dp[i][j] = a[i][j]; if(i == 1) max = -101;//注意:有出现全负,所以第一行应设为小于最小值。 else max = dp[i-1][j]; for(int k = 1 ; k <= j/2;k++) { if(j%k==0) if(max<dp[i][k]) max = dp[i][k]; } if(max < dp[i][j-1]) max = dp[i][j-1]; dp[i][j] += max; } } cout<<dp[n][m]<<endl; } return 0;}