ACM Steps_Chapter Three_Section2

来源:互联网 发布:ubuntu需求 编辑:程序博客网 时间:2024/06/01 09:32

Max Sum

#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;}


原创粉丝点击