题目:http://acm.hdu.edu.cn/showproblem.php?pid=3182
题意:有n个汉堡,每个汉堡有一个价值和做汉堡需要的体力,并且做有些汉堡前需要先做别的汉堡,问最多能做出多大价值
每个汉堡只能做一次并且有先后顺序,所以需要状压dp而不能直接暴力判断
做汉堡的前置关系可以用状压来简化判断
还可以预处理出每个状态需要花费的体力
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; int n,m,maxx; int cost[1<<15]; int a[20]; int dp[1<<15]; int v[20],e[20]; int main() { ios::sync_with_stdio(false); int T; cin>>T; while(T--) { cin>>n>>m; for(int i=0;i<n;i++) cin>>v[i]; for(int i=0;i<n;i++) cin>>e[i]; for(int i=0;i<n;i++) { a[i]=0; int x,y; cin>>x; while(x--) { cin>>y; y--; a[i]|=(1<<y); } } int tot=1<<n; memset(cost,0,sizeof(cost)); for(int i=0;i<tot;i++) { for(int j=0;j<n;j++) if ((i>>j)&1) cost[i]+=e[j]; } memset(dp,-1,sizeof(dp)); dp[0]=0; maxx=0; for(int i=0;i<tot;i++) { if (dp[i]==-1) continue; for(int j=0;j<n;j++) { if ((i>>j)&1) continue; if (cost[i]+e[j]>m) continue; if ((i&a[j])==a[j]) { dp[i|(1<<j)]=dp[i]+v[j]; maxx=max(maxx,dp[i|(1<<j)]); } } } cout<<maxx<<endl; } return 0; }
时间: 2024-10-09 10:58:28