题意翻译
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 ",ans); 30 return 0; 31 }