这道题做得很有成就感!虽然被某牛称为水题。。。
假如把题目给的数据放入一个n*n的矩阵中,对于每一层第i个格子为1,表示做出了第i个汉堡,为0表示没有做出这个汉堡。那么这一层可以做出这个汉堡的条件就是做出这些汉堡的前提条件全部满足,即做这个汉堡需要做的另外几个汉堡都已经做好。由此可以得到两层之间的状态转移关系。需要特别注意的是,因为每个汉堡都只会做一个,除了前提条件满足之外,还要求这个汉堡没有做过。
之前因为st[j]我全部是用一个函数现算,结果TLE。算了算时间应该不会超时,打表之后203msAC。
#include<stdio.h> #include<string.h> #include<cmath> #define N 16 int a[N],b[N],mark[N],st[N]; struct node { int x,y; } dp[N][1<<N]; int Max(int x,int y) { if(x>y) return x; return y; } int fun(int x) { return (int)pow(2,x-1); } int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); int i,j,k; for(i=1; i<=n; i++) scanf("%d",&a[i]); for(i=1; i<=n; i++) scanf("%d",&b[i]); for(i=1; i<=n; i++) { scanf("%d",&k); mark[i]=0; for(j=1; j<=k; j++) { int temp; scanf("%d",&temp); mark[i]+=(int)pow(2,temp-1); } } for(i=1; i<=n; i++) st[i]=fun(i); int t=1<<n; for(i=0; i<=n; i++) { for(j=0; j<t; j++) { dp[i][j].x=-1; dp[i][j].y=0; } } dp[0][0].x=0; for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { for(k=0; k<t; k++) { if((mark[j]&k)==mark[j]&&(st[j]&k)==0&&dp[i-1][k].x!=-1&&dp[i-1][k].y+b[j]<=m) { if(dp[i][k].x<dp[i-1][k].x+a[i]) { dp[i][st[j]+k].x=dp[i-1][k].x+a[j]; dp[i][st[j]+k].y=dp[i-1][k].y+b[j]; } else dp[i][st[j]+k]=dp[i][st[j]+k]; } } } } int max=0; for(i=1; i<=n; i++) { for(j=0; j<t; j++) max=Max(max,dp[i][j].x); } printf("%d\n",max); } return 0; }