hdu3159 FATE(二维费用背包板子题)

题意:就是裸的题目,跟背包9讲上的二维费用公式一模一样。

问题

二维费用的背包问题是指:对于每件物品,具有两种不同的空间耗费,选 择这件物品必须同时付出这两种代价。对于每种代价都有一个可付出的最大值 (背包容量)。问怎样选择物品可以得到最大的价值。 设这两种代价分别为代价一和代价二,第i件物品所需的两种代价分别 为Ci和Di。两种代价可付出的最大值(两种背包容量)分别为V 和U。物品的 价值为Wi

算法

费用加了一维,只需状态也加一维即可。设F[i,v,u]表示前i件物品付出两 种代价分别为v和u时可获得的最大价值。状态转移方程就是: F[i,v,u] = max{F[i−1,v,u],F[i−1,v−Ci,u−Di] + Wi} 如前述优化空间复杂度的方法,可以只使用二维的数组:当每件物品只可 以取一次时变量v和u采用逆序的循环,当物品有如完全背包问题时采用顺序的 循环,当物品有如多重背包问题时拆分物品。

#include 
#include 
#include 
#include  
using namespace std;
const int maxn = 1005;
int n, m, s, k;
int dp[maxn][maxn];
int a[maxn], b[maxn];
int main() {
    while(~scanf("%d%d%d%d", &n, &m, &k, &s)) {
        for(int i = 1; i <= k; i++) {
            scanf("%d%d", &a[i], &b[i]);
        }
        memset(dp, 0, sizeof(dp));
        for(int q = 1; q <= k; q++) {
            for(int i = b[q]; i <= m; i++) {
                for(int j = 1; j <= s; j++) {
                    dp[i][j] = max(dp[i][j], dp[i - b[q]][j - 1] + a[q]);
                }
            }
        }

        int flag = -1;
        for(int i = m; i >= 1; i--) {
                if(dp[i][s] >= n) {
                    flag=max(flag,m-i);
                }
        }
        printf("%d\n", flag);
    }
    return 0;
}

你可能感兴趣的:(ACM_DP)