CF-580D Kefa and Dishes (状压dp)

时间:2019-08-20
本文章向大家介绍CF-580D Kefa and Dishes (状压dp),主要包括CF-580D Kefa and Dishes (状压dp)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

原题链接CodeForces - 580D

题意:给你n种菜,吃每种菜都会得到对应的满足值。给出k种buff,如果先吃a再吃b 满足感就会提升c。最后你要吃共m种菜,能获得的最大满足值为多少。

思路:一开始会想到最短路之类的,相当于有向图。但是这是多源出发的最长路径(不会....),在看看题目范围 最多也就18种菜。所以我们就暴力状态dp一下,来得到结果。

code:  (dp要开long long)


#include <bits/stdc++.h> using namespace std; const int maxn = 1e5; long long dp[(1<<18)+5][18+5]; int arr[20]; int g[20][20]; int num[1<<18]; void getnum(){ for(int i = 0;i<(1<<18);i++){ for(int j=0;j<18;j++){ if(i&(1<<j)) num[i]++; } } } int main(){ getnum(); int n,m,q; while(cin>>n>>q>>m){ for(int i=0;i<n;i++){ cin>>arr[i]; } memset(g,0,sizeof(g)); for(int i=0;i<m;i++){ int u,v,w; cin>>u>>v>>w; g[u-1][v-1] = w; } memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ dp[1<<i][i] = arr[i]; } long long ans = 0; for(int i=0;i<(1<<n);i++){ for(int j=0;j<n;j++){ if(!(i&(1<<j))) continue;//判断右数第j位是否为1 for(int k=0;k<n;k++){ if(i&(1<<k)) continue; int state = i|(1<<k);//将i上右数第k位变为1 dp[state][k] = max(dp[state][k],dp[i][j]+g[j][k]+arr[k]); } if(num[i]==q) ans = max(ans,dp[i][j]); } } cout<<ans<<endl; } }

原文地址:https://www.cnblogs.com/Tianwell/p/11381835.html