hdu 4501 多维背包

来源:互联网 发布:网络协议的作用 编辑:程序博客网 时间:2024/06/06 03:54

直接将01背包搬到多维背包不能想当然,有两个细节需要注意下。

1.多个限制条件不能直接放到for循环中限制,因为各个状态是相互不限制的,放到for循环变量中限制是与的关系,放到{}中的限制是或的关系。

错位代码:

for(int i=0;i<n;i++)            for(int j=v1;j>=a[i];j--)                for(int p=v2;p>=b[i];p--)                    for(int q=k;q>=1;q--)

2.状态转移在判断过程需要一个temp变量记录,不能三个状态同时转移,这是发现与样例不符合修改的,动归理解不深,我觉得可能是状态重叠导致的错误。

错误代码:

if(j>=a[i])      dp[j][p][q]=max(dp[j][p][q],dp[j-a[i]][p][q]+val[i]);if(p>=b[i])       dp[j][p][q]=max(dp[j][p][q],dp[j][p-b[i]][q]+val[i]);if(q>=1)       dp[j][p][q]=max(dp[j][p][q],dp[j][p][q-1]+val[i]);
最后是修改后的AC代码:

#include <algorithm>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <vector>#include <map>#include <set>using namespace std;typedef long long ll;int n,v1,v2,k;int a[110],b[110],val[110];int dp[110][110][10];int main(){    while(~scanf("%d%d%d%d",&n,&v1,&v2,&k))    {        for(int i=0;i<n;i++)            scanf("%d%d%d",&a[i],&b[i],&val[i]);        memset(dp,0,sizeof(dp));        for(int i=0;i<n;i++)            for(int j=v1;j>=0;j--)                for(int p=v2;p>=0;p--)                    for(int q=k;q>=0;q--)        {            int ans=0;            if(j>=a[i])                ans=max(ans,dp[j-a[i]][p][q]+val[i]);            if(p>=b[i])                ans=max(ans,dp[j][p-b[i]][q]+val[i]);            if(q>=1)                ans=max(ans,dp[j][p][q-1]+val[i]);            dp[j][p][q]=max(ans,dp[j][p][q]);        }        printf("%d\n",dp[v1][v2][k]);    }    return 0;}



0 0