codeforces 580d 状压DP
Posted 十目
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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-10 typedef 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的主要内容,如果未能解决你的问题,请参考以下文章
CF580D Kefa and Dishes 状压dpBy cellur925
codeforces 580D:Kefa and Dishes