hdu 3182 Hamburger Magi

来源:互联网 发布:epub手机打开知乎 编辑:程序博客网 时间:2024/04/30 18:33

http://acm.hdu.edu.cn/showproblem.php?pid=3182
建议先做hdu 1074题。
同1074题思路差不多,但这里加了条件判断,即判断做第k个汉堡是是否做出了它的所有先决汉堡,对于每个先决汉堡,也要进行相同的判定。这显然有点难度。
优化的一个思路是在初始化时将所有dp.value初始化为负无限大,只有dp[0].value=0。此时,对于任意一种情况,只要没有先决条件为0的子情况,其value无限小。
最后遍历一边数组,找出其最大value即可。
博主在这里提供另一种思路:i表示某种可能发生的情况,对于所有未完成的汉堡k,判断其先决汉堡是否在i这种情况中完成了,完成,即更新dp[i+k].value。否则dp[i+k].value为无限小。

#include<iostream>#include<cstdio>using namespace std;const int N=15;#define max(a,b) a>b?a:b;struct DPT{    int value;    int energy;//到此种情况剩余的能量    DPT()    {        energy=0;    }}dp[(1<<N)+5];int a[N];int b[N];int c[N][N]; //储存某种汉堡的先决汉堡的二进制值int main(){    int t;    cin>>t;    while(t--)    {        memset(c,0,sizeof(c));        int n,m;        cin>>n>>m;        for(int i=0;i<n;i++)            cin>>a[i];        for(int i=0;i<n;i++)            cin>>b[i];        for(int i=0;i<n;i++)        {            cin>>c[i][0];            for(int j=1;j<=c[i][0];j++)            {                int bb;                cin>>bb;                c[i][j]=(1<<(bb-1));            }        }        int end=1<<n;        for(int i=1;i<end;i++)            dp[i].value=-100000;        dp[0].value=0;        dp[0].energy=m;        for(int i=1;i<end;i++)        {            bool judge=false;            for(int j=n-1;j>=0;j--)            {                judge=false;                int k=1<<j;                if(k&i)                {                    int tmp=i-k;                    //如果上一种情况剩余的能量大于等于制作第j份汉堡的能量,且第j份汉堡的先决汉堡应该已经完成                    if(dp[tmp].energy<b[j])                        continue;                    for(int kk=1;kk<=c[j][0];kk++)                        if(!(tmp&c[j][kk]))                        {                            judge=true;                            break;                        }                    if(judge) continue;                    if(dp[i].value<dp[tmp].value+a[j])                    {                        dp[i].value=dp[tmp].value+a[j];                        dp[i].energy=dp[tmp].energy-b[j];                    }                    else if(dp[i].value==dp[tmp].value+a[j]&&dp[i].energy<dp[tmp].energy-b[j])                    {                        dp[i].energy<dp[tmp].energy-b[j];                    }                }            }        }        int maxn=0;        for(int i=end-1;i>0;i--)            maxn=max(dp[i].value,maxn);        cout<<maxn<<endl;    }    return 0;}
0 0
原创粉丝点击