HDU - 3182 Hamburger Magi (坑了我一天的简单DP!!!)

题目描述:

点击打开链接

题意:有N个汉堡,你有一定的能量值E,每个汉堡有自己的价值v,并且制作需要花费一定的能量值e,但是有些汉堡制作需要先制作一些特定的汉堡才行,求怎样制作汉堡能够获得的最大的价值。

这题其实不难,但是我坑在了一个十分愚蠢的地方,很气,于是要写下这道题。首先状态是十分好设计,汉堡最多只有15个,那么直接采取状态压缩,dp[i][j]表示i状态下使用了j能量时获得的价值。直接枚举所有状态,加进汉堡时在检验一下是否能加,能加的话更新状态和答案。这题唯一的坑点在于在枚举状态时,存在某些状态本身不可行的情况。这个问题其实也非常好解决,先把所有状态的初值设为-1,dp[0][0]设为0,因为该状态必然可行,并且所有状态肯定是从该状态转移得来的,所以自然从dp[0][0]开始进行状态转移,那么所有可行的状态都会被赋值,所以对后面状态枚举时只需检验他是否为-1即可。这个方法其实我很快就想到了,但是我坑在了一个极为愚蠢的地方,我把ans初始化成了-1,但是存在所有状态都不可行的情况,这个时候无法转移,答案就是0,我居然想了那么久都没想到!!!

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXM=25;

int N,E;
int n[20];
int e[20];
int dp[1<<16][110];
vector need[20];

int cal(int x)
{
    int hav=0;
    for (int i=1;i<=N;i++)
    {
        if (x&(1<<(i-1)))
            hav=hav+e[i];
    }
    return hav;
}
bool check(int state,int x)
{
    for (int i=0;i<(int)need[x].size();i++)
        if (!(state&(1<<(need[x][i]-1)))) return false;
    return true;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&N,&E);
        for (int i=1;i<=N;i++)
            scanf("%d",&n[i]);
        for (int i=1;i<=N;i++)
            scanf("%d",&e[i]);
        int q;
        for (int i=0;i<20;i++)
            need[i].clear();
        for (int i=1;i<=N;i++)
        {
            scanf("%d",&q);
            int x;
            while(q--)
            {
                scanf("%d",&x);
                need[i].push_back(x);
            }
        }
        memset(dp,-1,sizeof(dp));
        dp[0][0]=0;
        int ans=0;//愚蠢的我被这里坑了。。。QAQ。
        for (int i=0;i<(1<E) continue;
                    if (i&(1<<(j-1))) continue;
                    if (check(i,j))
                    {
                        int state=i|(1<<(j-1));
                        dp[state][hav+e[j]]=dp[i][hav]+n[j];
                        ans=max(ans,dp[state][hav+e[j]]);
                    }
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(DP)