zoukankan      html  css  js  c++  java
  • CF580D Kefa and Dishes(状压DP)题解

    思路

    (n leq 18),一看就很状压。

    (f_{st,i})为当前状态为(st)(二进制下第(x)位为(1)时表示选了第(x)个),最后一个选了(i)时的最大满意度(记录(i)是为了计算吃菜顺序的额外贡献),则有:

    [f_{st,i} = max(f_{pre,j} + a_i + c_{j,i}) ]

    其中,(j)必须在状态(st)时被选中,(pre)(st)不选(i)时的状态。

    至于统计答案,把(st)(1)的个数为(m)时的(f)(min)就可以了。

    代码

    #include <cstdio>
    #include <algorithm>
    #define LL long long
    
    using namespace std;
    
    const int maxn = 3e5 + 10;
    int n,k,m;
    LL a[20],c[20][20],f[maxn][20];
    
    int cnt(int x){
        int num = 0;
        while(x) num += (x & 1), x >>= 1; 
        return num;
    }
    
    int main(){
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 0; i < n; ++ i) scanf("%lld", &a[i]);
        for(int i = 1; i <= k; ++ i){
            int x,y; scanf("%d%d", &x, &y);
            scanf("%lld", &c[x - 1][y - 1]);
        } LL Ans = 0;
        for(int st = 0; st < (1 << n); ++ st){
            for(int i = 0; i < n; ++ i){
                bool flag = 0;
                if(st & (1 << i)){
                    for(int j = 0; j < n; ++ j){
                        if(j == i || !(st & (1 << j))) continue;
                        flag = 1;
                        f[st][i] = max(f[st][i], f[st ^ (1 << i)][j] + a[i] + c[j][i]);
                    }
                    if(!flag) f[st][i] = a[i];
                }
                if(cnt(st) == m) Ans = max(Ans, f[st][i]);
            }
        }
        printf("%lld
    ", Ans);
        return 0;
    }
    
  • 相关阅读:
    咨询
    xcode技巧
    礼仪
    asi 网络框架
    iOS 开发问题 书籍 价值 改名 创业大赛app
    PS,UI,美工
    运营推广
    多线程 并发 文章
    手机技巧 文章
    javaScript 类文章
  • 原文地址:https://www.cnblogs.com/whenc/p/13972815.html
Copyright © 2011-2022 走看看