SGU104 二维dp

大致题意: n个东西放在(1.2.3.。。m)个容器中,先放的必需在后方的左边。a[i][j]表示i号物品放在j容器所得
的价值,求最大价值。
几乎是刚刚开始接触动态规划题,开始我这样想 每个东西一件一件放,dp[k]表放k物品时候已经到达最大值
dp[k]=dp[k-1]+max(放k物品所得到最大值),这样想想不行,如果现在放最大值未必最大啊。
百度一下,发现别人用二维数组,我马上想想得二维的,于是dp[i][j]第i次放置放j容器时,所得最大值。
这样:dp[i][j]=max(dp[i-1][k])(k<=j-1;k>=i-1);画了个图,第i次选择j就是前一次中所有可能情况最大值,

这样地推,必然得到最大。最后在更新时候记录路经即可。

PS:不会dp的acmer能叫acmer吗!需要更多的dp来鞭挞我啊!渴望!

#include<iostream>   //1A  ,31ms
#include<cstdio>
using namespace std;
int nowmax[110][110];
int a[110][110];
int n,m;
void readin()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
       {
           cin>>a[i][j];
       }
   for(int i=1;i<=m;i++)
       nowmax[1][i]=a[1][i];
}
int fa[105][105];
int way[105];int num=0;
int main()
{
    readin();
     for(int i=2;i<=n;i++)
       for(int j=i;j<=m-(n-i);j++)   //对每个i,j
        {
            int maxid=1;
            int max=nowmax[i-1][i-1];
            for(int k=j-1;k>i-1;k--)   //更新找最大的
            {
                if(nowmax[i-1][k]>max)
                  {
                      max=nowmax[i-1][k];
                      maxid=k;
                  }
            }
            nowmax[i][j]=a[i][j]+max;
            fa[i][j]=maxid;
        }
    int ans=nowmax[n][m];
    int anslast=m;
    for(int k=n;k<m;k++)
        {
            if(ans<nowmax[n][k])
             {
                 ans=nowmax[n][k];
                 anslast=k;
             }
        }
        cout<<ans<<endl;
        int maxid=anslast;
     way[num++]=anslast;
    for(int i=n;i>1;i--)
    {
        way[num++]=fa[i][maxid];
        maxid=fa[i][maxid];
    }
     for(int i=num-1;i>=0;i--)
    {
        if(i!=0)printf("%d ",way[i]);
        else printf("%d
",way[i]);
    }
}


原文地址:https://www.cnblogs.com/yezekun/p/3925725.html