zoukankan      html  css  js  c++  java
  • 上决╇ф人员分配问题 (背包问题)

      题目链接--上决╇ф人员分配问题

      比赛的时候一直过不了这题。$dp(i,j,k)$表示从前$i$个Acmer中选择$j$个能取得的最大战斗力,并且战斗力不超过$k$。

      转移方程$dp(i,j,k)=max{dp(i-1, j, k), dp(i-1, j-1, k-a[i]) + a[i]}$,记得判断一下前驱状态是否可以到达。

    AC代码

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int maxn = 30 + 5;
    int a[maxn];
    int dp[maxn][maxn][1000], f[maxn][maxn][1000];
    
    int solve(int n, int tol) {
        memset(dp, 0, sizeof(dp));
        memset(f, 0, sizeof(f));
        int sum = tol / 2;
        for(int i = 0; i <= n; i++) 
            for(int k = 0; k <= sum; k++)
                f[i][0][k] = 1;
        
    
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n/2; j++) {
                for(int k = 1; k <= sum; k++) {
                    dp[i][j][k] = dp[i-1][j][k];
                    f[i][j][k] = f[i-1][j][k];
                    if(k-a[i] >= 0 && f[i-1][j-1][k-a[i]] && dp[i-1][j-1][k-a[i]] + a[i] <= sum) {
                        f[i][j][k] = 1;
                        dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k-a[i]] + a[i]);
                    }
                }
            }
        }
        return tol - 2 * dp[n][n/2][sum];
    }
    
    int main() {
        int n;
        while(scanf("%d", &n) == 1) {
            int tol = 0;
            for(int i = 1; i <= 2*n; i++) {
                scanf("%d", &a[i]);
                tol += a[i];
            }
            printf("%d
    ", solve(2*n, tol));
        }
        return 0;
    }

    如有不当之处欢迎指出!

     

  • 相关阅读:
    04_Windows平台Spark开发环境构建
    Hadoop Streaming 使用及参数设置
    Kafka 及 PyKafka 的使用
    Database Subquery
    Miscellaneous
    Emacs
    算法归纳
    逆元求组合数
    Elasticsearch 原理
    Linux的内存分页管理【转】
  • 原文地址:https://www.cnblogs.com/flyawayl/p/8921835.html
Copyright © 2011-2022 走看看