Codeforces 580D Kefa and Dishes(状压DP)
题目大概说要吃掉n个食物里m个,吃掉各个食物都会得到一定的满意度,有些食物如果在某些食物之后吃还会增加满意度,问怎么吃满意度最高。
- dp[S][i]表示已经吃掉的食物集合是S且刚吃的是第i个食物的最大满意度
。。没什么好说的
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 5 int val[18],pairs[18][18]; 6 long long d[1<<18][18]; 7 8 int getCnt(int s){ 9 int cnt=0; 10 for(int i=0; i<18; ++i){ 11 if(s>>i&1) ++cnt; 12 } 13 return cnt; 14 } 15 16 int main(){ 17 int n,m,k; 18 scanf("%d%d%d",&n,&m,&k); 19 for(int i=0; i<n; ++i){ 20 scanf("%d",val+i); 21 } 22 int a,b,c; 23 while(k--){ 24 scanf("%d%d%d",&a,&b,&c); 25 --a; --b; 26 pairs[a][b]=c; 27 } 28 for(int i=0; i<n; ++i){ 29 d[1<<i][i]=val[i]; 30 } 31 for(int s=0; s<(1<<n); ++s){ 32 for(int i=0; i<n; ++i){ 33 if((s>>i&1)==0) continue; 34 for(int j=0; j<n; ++j){ 35 if(i==j || (s>>j&1)==0) continue; 36 d[s][i]=max(d[s][i],d[s^(1<<i)][j]+val[i]+pairs[i][j]); 37 } 38 } 39 } 40 long long res=0; 41 for(int s=0; s<(1<<n); ++s){ 42 if(getCnt(s)!=m) continue; 43 for(int i=0; i<n; ++i){ 44 res=max(res,d[s][i]); 45 } 46 } 47 printf("%lld",res); 48 return 0; 49 }