首页 > 代码库 > codeforces 580d 状压DP
codeforces 580d 状压DP
题意:有n种菜,现在选m种菜来吃,如果在吃y的前一道菜是x的话,那么就可以获得额外满意度。每一种菜都有一个满意度。
思路:设dp[i][S]表示为最后一道菜为i,现在的菜吃的状态为S。S中的二进位如果为1表示已经吃了,如果是0则表示没吃,状压DP,答案就出了。
#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <map>#include <vector>#include <queue>using namespace std;#define EPS 1e-10typedef long long ll;const int maxn = 1<<20;const int INF = 1e9 ;const double eps = 1e-8;const int mod = 2520;int gra[20][20],a[20],num[20],cnt;ll dp[maxn][20];int cal(int u){ cnt = 0; int cntp = 0; while(u > 0){ if(u % 2 == 1) num[++cnt] = cntp; cntp++; u /= 2; } return cnt;}int main(){ // freopen("in.txt","r",stdin); int n,m,k; scanf("%d%d%d",&n,&m,&k); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); int se = (1<<n) - 1; int a1,b,c; for(int i = 1;i <= k;i++){ scanf("%d%d%d",&a1,&b,&c); gra[a1][b] = c; } ll smax = 0; for(int i = 1;i <= se;i++){ if(cal(i) > m) continue; ll sum = 0; for(int j = 1;j <= cnt;j++){ int posj = num[j]; // cout<<posj+1<<" "; // int posj = num[j]; // dp[i][posj] = sum; for(int k = 1;k <= cnt;k++){ if(k == j&&cnt != 1) continue; int posk = num[k]; dp[i][posj] = max(dp[i][posj],dp[i-(1<<posj)][posk] + gra[posk+1][posj+1] + a[posj+1]); // cout<<posk+1<<" "<<dp[i][posj]<<" "<<"b"; } // cout<<endl; smax = max(smax,dp[i][posj]); } } printf("%I64d\n",smax); return 0;}
codeforces 580d 状压DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。