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);
    }
  • 相关阅读:
    5.Spring高级装配(根据profile的激活状态决定使用的环境) 以及 条件化 Bean
    4.SpringJunit4ClassRunner
    3.Spring配置可选方案
    2.Spring容器bean的生命周期
    1.使用spring上下文容纳你的Bean
    maven 打包跳过 Junit test
    HTML5中meta name="viewport"
    二、JavaScript this
    VIM_插件
    VBS_DO...Loop
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11417179.html
Copyright © 2011-2022 走看看