Codeforces 580D-Kefa and Dishes(状压DP)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 580D-Kefa and Dishes(状压DP)相关的知识,希望对你有一定的参考价值。

原题链接:http://codeforces.com/problemset/problem/580/D

 

题意:在n个数字中有顺序地选择m个数字,每个数字对应有个值ai,每取一个数字答案加上ai,并且存在k个关系:x y c,如果x恰好排在y的前面,那么答案再加上ci的值。输出最大值。

 

思路:状压dp。dp[i][j]中,i是已经选了若干个数的情况,j是最后一个被选取的数,i从选取1个到m个枚举下去,j从第1个数到第n个数进行枚举就能得到答案。

 

AC代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 typedef long long LL;
 6 LL a[20],d[20][20],pos[20];
 7 LL dp[1<<19][20]; 
 8 int main()
 9 {
10     pos[0]=1;
11     for(int i=1;i<=19;i++) pos[i]=pos[i-1]<<1;
12     memset(dp,0, sizeof(dp));
13     memset(d, 0, sizeof(d));
14     int n,m,k,x,y,c;
15     scanf("%d %d %d", &n, &m, &k);
16     for(int i=0;i<n;i++) scanf("%I64d", a+i);
17     for(int i=0;i<k;i++){
18         scanf("%d %d %d",&x, &y, &c);
19         x--,y--;
20         d[x][y]=c;
21     }
22     int num;
23     for(int i=0;i<n;i++) dp[pos[i]][i]=a[i];
24     
25     for(int t=1;t<m;t++){
26         for(int i=0;i<n;i++){
27             for(int j=0;j<pos[n];j++){
28                 if(j&pos[i]) continue;
29                 
30                 num=0;//cout<<‘*‘<<endl;
31                 k=j;
32                 while(k){
33                     if(k&1)
34                         num++;
35                     k>>=1;
36                 }        
37                 if(num!=t) continue;
38                 
39                 for(int s=0;s<n;s++)
40                     if(s!=i&&(j&pos[s])){
41                         dp[j|pos[i]][i]=max(dp[j|pos[i]][i], dp[j][s]+d[s][i]+a[i]);
42                         //cout<<s<<‘ ‘<<j<<‘ ‘<<i<<‘ ‘<<d[s][i]<<‘ ‘<<dp[j|pos[i]][i]<<endl;
43                     }
44                     
45             }
46         }
47     }
48     
49     LL ans=0;
50     for(int i=0;i<pos[n];i++){
51         num=0;
52         k=i;
53         while(k){
54             if(k&1)    
55                 num++;
56             k>>=1;
57         }
58         if(num!=m) continue;
59         
60         for(int j=0;j<n;j++) if(pos[j]&i) ans=max(ans, dp[i][j]);
61     }
62     printf("%I64d\n", ans);
63     return 0;
64 }

 

以上是关于Codeforces 580D-Kefa and Dishes(状压DP)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 580D:Kefa and Dishes

[2016-03-23][codeforces][580][A][Kefa and First Steps]

Kefa and Park CodeForces - 580C

codeforces 580C Kefa and Park (树上DFS)

Codeforces 580D Kefa and Dishes(状态压缩DP)

Codeforces Round #580 (Div. 1)