您的位置:首页 > 其它

HDOJ 3182 Hamburger Magi

2016-07-04 10:20 232 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3182

题意:给我们一些汉堡的价值以及制作成本,再给出每一个汉堡做之前的前置条件,问我们在有一定钱的情况下能做出来的最大的价值是多少。

如果去掉这个前置条件的话就是一道普普通通的背包题目,因为多了一个前置条件,所以我们必须讨论当前的每一种情况,也就是说,我们得用状压dp来完成,我们用2进制数来表示当前情况,在第i位上是1表示我们已经完成了第i件物品的制作,所以我们的状态转移方程为:dp[i|now] = dp[now] + dp[i]。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 17;
int ord[maxn][maxn],dp[1<<maxn],rest[1<<maxn],cost[maxn], val[maxn];
int n, V;
int judge(int m, int cur)
{
for(int i = 1; i <= ord[m][0]; i++)
if(!(cur & (1<<(ord[m][i]-1))))
return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&V);
for(int i = 1; i <= n; i++) scanf("%d",&val[i]);
for(int i = 1; i <= n; i++) scanf("%d",&cost[i]);
for(int i = 1; i <= n; i++)
{
scanf("%d",&ord[i][0]);
for(int j = 1; j <= ord[i][0]; j++)
scanf("%d",&ord[i][j]);
}
for(int i = 0; i <= (1<<n)-1; i++)
{
dp[i] = -1111;
rest[i] = 0;
}
dp[0] = 0;
rest[0] = V;
int ans = 0;
for(int i = 0; i <= (1<<n)-1; i++)
for(int j = 1; j <= n; j++)
{
if(i & 1<<(j-1)) continue;
int now = i | (1<<(j-1));
if(dp[now] < dp[i]+val[j] && judge(j,i) && rest[i] >= cost[j])
{
dp[now] = dp[i]+val[j];
rest[now] = rest[i] - cost[j];
ans = max(ans, dp[now]);
}
}
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: