标签:
题意: 有n个菜,需要m个菜,k个规则
每个菜吃下去的满足感为 a1......an
每个规则: 吃完第u个菜后吃第v个菜满足感+c;
问:怎么吃才能幸福感最大?
dp[1<<18][20]:一维表示吃了的菜(1表示吃了,0表吃没吃),第二维表示最后一个吃的菜
dp的初始化: dp[1<<i][i] = saty[i];
状态转移:dp[i|(1 << k)][k] = max(dp[i][j] + rule[j][k] + safy[k],dp[i|(1 << k)][k]);
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 typedef long long ll; 9 10 /* 11 n,m,r 12 */ 13 ll n,m,r,safy[20],dp[1<<18][20],rule[20][20]; 14 int main(){ 15 16 while(scanf("%d%d%d",&n,&m,&r) != EOF){ 17 memset(rule,0,sizeof(0)); 18 memset(dp,-1,sizeof(dp)); 19 for(int i = 0 ; i < n ; i ++) scanf("%d",&safy[i]); 20 for(int i = 0 ; i < r ; i ++){ 21 int u,v,s; 22 scanf("%d%d%d",&u,&v,&s); 23 u-- ; v --; rule[u][v] = s; 24 } 25 26 for(int i = 0 ; i < n ; i ++){ 27 dp[1<<i][i] = safy[i]; 28 } 29 ll ans = 0; 30 for(int i = 0 ; i < (1<<n) ; i ++){ //*** *** 遍历每种状态 31 32 ll tmp = i; 33 ll cnt = 0; 34 while(tmp){ 35 if(tmp & 1) cnt ++; 36 tmp >>= 1ll; 37 } 38 bool can = false; 39 if(cnt == m) can = true; 40 41 for(int j = 0 ; j < n ; j ++){ //*******遍历最后吃过的 j 42 43 if(dp[i][j] == -1) continue; //还没有出现这种情况 44 if(can) ans = max(ans,dp[i][j]); // 满足条件,更新答案 45 for(int k = 0 ; k < n ; k ++){ //******吃第k个 46 if(i & (1 << k )) continue; //k已经吃过了 47 dp[i|(1 << k)][k] = max(dp[i][j] + rule[j][k] + safy[k],dp[i|(1 << k)][k]); 48 } 49 } 50 } 51 printf("%I64d\n",ans); 52 } 53 return 0; 54 }
Codeforces Round #321 (Div. 2) D. Kefa and Dishes (状压dp,再A一发)
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5405923.html