[CF580D]Kefa and Dishes

题意翻译

kefa进入了一家餐厅,这家餐厅中有n个菜(0<n<=18),kefa对第i个菜的满意度为ai(0<=ai<=10^9),并且对于这n个菜有k个规则,如果kefa在吃完第xi个菜之后吃了第yi个菜(保证xi、yi不相等),那么会额外获得ci(0<=ci<=10^9)的满意度。kefa要吃m道任意的菜(0<m<=n),但是他希望自己吃菜的顺序得到的满意度最大,请你帮帮kefa吧!

输入第一行是三个数:n,m,k

第二行是n个数,第i个数表示kefa对第i道菜的满意度为ai

第三行到第k+2行每行有3个数:xi,yi,ci,表示如果kefa在吃完第xi道菜之后立刻吃了第yi道菜,则会额外获得ci的满意度

Ps:这道题是个状压,因为n,m的范围都很小

 

简单的状压$dp$

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define ll long long
 5 using namespace std;
 6 int n,m,p;ll ans;
 7 ll a[20],sum[1<<20],val[20][20],f[1<<20][20];
 8 int main() {
 9     scanf("%d%d%d",&n,&m,&p);
10     for(int i=0;i<n;i++) scanf("%lld",&a[i]);
11     for(int i=1;i<=p;i++) {
12         int x,y,z;scanf("%d%d%d",&x,&y,&z);
13         x--,y--;val[x][y]=z;
14     }
15     for(int i=1;i<(1<<n);i++) sum[i]=sum[i>>1]+(i&1);
16     for(int i=0;i<n;i++) f[1<<i][i]=a[i];
17     for(int i=0;i<(1<<n);i++)
18         for(int j=0;j<n;j++) {
19             if(((1<<j)&i)==0) continue;
20             for(int k=0;k<n;k++) {
21                 if(((1<<k)&i)!=0) continue;
22                 f[i|(1<<k)][k]=max(f[i|(1<<k)][k],f[i][j]+val[j][k]+a[k]);
23             }
24         }
25     for(int i=0;i<(1<<n);i++)
26         for(int j=0;j<n;j++)
27             if(sum[i]==m)
28                 ans=max(ans,f[i][j]);
29     printf("%lld\n",ans);
30     return 0;
31 }

 

posted @ 2018-11-30 09:10  Slr  阅读(124)  评论(0编辑  收藏  举报