zoukankan      html  css  js  c++  java
  • 状压dp CodeForces

    题意:共有 N 道菜,每道菜有一个满意值,小明要吃 M 道菜,其中有 K 种组合可以让小明连续吃下他们后获得额外的满意值,求最大满意值。

    分析:因为菜的数量只有18,而且要考虑先后连续的顺序和吃 M 道菜停止 ,就要想到要明确表示出小明吃菜的状态,就可以用状压DP来做。状态用总的状态(二进制的state )和正在吃的菜( i )表示

    状态转移方程:dp[sta | tmp2][ j ] = max(dp[sta | tmp2][ j ], dp[sta]  [i ] + com[ i ] [ j ] + a[ j ])

    注意,i 从 1 扫到 N,但吃的菜不是(1<<i)而是 ( 1<<( i -1 ) )。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 0x3f3f3f3f
    using namespace std;
    
    typedef long long ll;
    const int maxn = 19;
    int n, m, k;
    ll a[maxn];
    ll dp[1 << maxn][19];
    ll com[maxn][maxn];
    int main() {
        scanf("%d%d%d", &n, &m, &k);
        for (int i = 1; i <= n; i++) {
            scanf("%d", a + i);
        }
        int x, y, z;
        for (int i = 1; i <= k; i++) {
            scanf("%d%d%d", &x, &y, &z);
            com[x][y] = z;
        }
        for (int i = 1; i <= n; i++) {
            dp[1 << (i - 1)][i] = a[i];
        }
        int tot = (1 << n);
        int sta;
        ll ans = 0;
        for (int sta = 0; sta < tot; sta++) {
            // if(dp[sta]==0)
            int cnt = 0;
            for (int i = 1; i <= n; i++) {
                int tmp1 = 1 << (i - 1);
                // printf("sta=%d
    ", sta);
                if (tmp1 & sta) {
                    cnt++;
                    for (int j = 1; j <= n; j++) {
                        if (j == i) continue;
                        int tmp2 = 1 << (j - 1);
                        if (!(sta & tmp2)) {
                            // cnt++;    `
                            // dp[sta|tmp2]+=a[j];
                            dp[sta | tmp2][j] = max(dp[sta | tmp2][j], dp[sta][i] + com[i][j] + a[j]);
                            // printf("com%d %d=%lld
    ",i,j,com[i][j]);
                            // ans = max(ans, dp[sta | tmp2]);
                        }
                    }
                }
            }
            // printf("yes cnt=%d
    ",cnt);
            if (cnt == m) {
                for (int i = 1; i <= n; i++) {
                    if ( sta & (1 << (i - 1)) ) {
                        ans = max(ans, dp[sta][i]);
                    }
                }
            }
    
        }
        printf("%lld
    ", ans);
    }
  • 相关阅读:
    R.java文件介绍
    Windows CE Notification API的使用方法
    Vue.js组件的重要选项
    Vue.js如何划分组件
    细数那些年我用过的前端开发工具
    前端几个常用简单的开发手册拿走不谢
    Bootstrap相关优质项目学习清单
    前端页面实现报警器提示音效果
    人工智能面试题86问,新手找工作必备!
    人工智能面试题86问,新手找工作必备!
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11417179.html
Copyright © 2011-2022 走看看