动态规划开始的开始(为什么要用一个数组而不是两个)

来源:互联网 发布:网络用语沙发的意思 编辑:程序博客网 时间:2024/06/13 05:03

国际惯例

http://acm.nyist.net/JudgeOnline/problem.php?pid=49

题意:T组数据,每组第一行两个数分别是最多能花的钱数,和要买的物品的个数n,接下来n行是每种物品的价钱和重要程度。求最这个钱数下,最多能达到的价钱和重要程度乘积和的最大值

分析:很简单的以第几个物品为第一层,以钱数为第二层。按照记忆中进行两层dp,并开辟一个二维数组。却出现错误

错误代码如下(及分析):

#include <iostream>#include <cstdio>#include <algorithm>#include <queue>#include <cstring>using namespace std;struct T{    int p,v;}a[105];int dp[205][30005];int main(){    freopen("in.txt","r",stdin);    int T;    int m,n;    scanf("%d",&T);    while(T--)    {        memset(dp,0,sizeof(dp));        scanf("%d%d",&m,&n);        for(int i = 0; i < n; i ++)        {            scanf("%d%d",&a[i].p,&a[i].v);            //cout<<a[i].p<<a[i].v<<endl;        }        int ans = 0;        for(int i = 0; i < n; i ++)        {            for(int j = m; j >= a[i].p; j --)            {                if(i == 0)                dp[i][j] = a[i].v * a[i].p;                else                dp[i][j] = max(dp[i - 1][j],dp[i - 1][j-a[i].p ] + a[i].v * a[i].p);                ans = max(ans,dp[i][j]);/*问题出现次数并不一定是上一个的dp[i - 1][j]是最大的,即有可能是dp[0][j]是最大的,此处无法保障 如下面这组数据1000 5300 5400 3200 2800 2400 5当dp[2][305]时候,向上推dp[1][305]时因为j是从a[i].p开始的,所以并没能经过该点,也就是说该点是零因此dp[2][305]是零。与实际情况不符*/ }        }        printf("%d\n",ans);    }    return 0;}
优美代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <queue>#include <cstring>using namespace std;struct T{    int p,v;} a[105];int dp[30005];int main(){    //freopen("in.txt","r",stdin);    int T;    int m,n;    scanf("%d",&T);    while(T--)    {        memset(dp,0,sizeof(dp));        scanf("%d%d",&m,&n);        for(int i = 0; i < n; i ++)        {            scanf("%d%d",&a[i].p,&a[i].v);        }        for(int i = 0; i < n; i ++)        {            for(int j = m; j >= a[i].p; j --)            {                dp[j] = max(dp[j],dp[j-a[i].p ] + a[i].v * a[i].p);//将dp数组变成一维的,不用考虑i是否                  //为零的问题,而且保证了dp[j]肯定是所有层次,及所有物品中的最大值             }        }        printf("%d\n",dp[m]);    }    return 0;}




0 0