HDU3496 Watch the moive (二维01背包)
2017-07-23 16:29
344 查看
题目大意
题目分析
题目类型分析
如何构建DP
二维费用背包传统解法
二维费用背包降维
AC代码
初始化方式v代表花费的件数u代表花费的时间
初始化方式v代表花费的时间u代表花费的件数
原题链接
两个限制条件:1,看movie的总时间<=L; 2,只能看M部,M<=N.
求多多能获得的最大幸福指数。
物品的费用之一:时间,选择电影i,就要花费相应的时间t[i];
物品的费用之二:件数,选择电影i,总的件数就要减1。
因为是0-1背包,所以我们需要逆序遍历二维费用:花费的时间,花费的件数。
f[i][v][u]=max{f[i-1][v][u],f[i-1][v-a[i]][u-b[i]]+w[i]}
针对本题,我们有两种选择:
v代表花费的时间,u代表花费的件数
v代表花费的件数,u代表花费的时间
这两者没用实质上的区别,区别的地方在于初始化dp时的方式不同。
回顾题目,我们发现:店家只卖M张碟。也就是说,在件数这个维度上,我们必须达到M维,多不行,少也不行,也就是我们常说的“刚好装满背包”。不过,对于时间维度L,最后看完M张碟的时间<=L就可以了。
当我们选择方式1:v代表花费的时间,u代表花费的件数时:
为了让u维(件数维)刚好装满,我们需要初始化dp[][]矩阵的第一列为0,其他列为-INF.
当我们选择方式2:v代表花费的件数,u代表花费的时间:
为了让v维(件数维)刚好装满,我们需要初始化dp[][]矩阵的第一行为0,其他行为-INF.
题目分析
题目类型分析
如何构建DP
二维费用背包传统解法
二维费用背包降维
AC代码
初始化方式v代表花费的件数u代表花费的时间
初始化方式v代表花费的时间u代表花费的件数
原题链接
题目大意
多多有N部最喜欢的movie,每一部需要话费时间t[i],给她带来的幸福指数为v[i]。两个限制条件:1,看movie的总时间<=L; 2,只能看M部,M<=N.
求多多能获得的最大幸福指数。
题目分析
题目类型分析
这是一道典型的二维费用背包问题。物品是电影,看或不看,0-1选择。物品的费用之一:时间,选择电影i,就要花费相应的时间t[i];
物品的费用之二:件数,选择电影i,总的件数就要减1。
因为是0-1背包,所以我们需要逆序遍历二维费用:花费的时间,花费的件数。
如何构建DP
二维费用背包传统解法
传统的二维费用是采用一个三维表,设f[i][v][u]表示前i件物品付出两种代价分别为v和u时可获得的最大价值。状态转移方程就是:f[i][v][u]=max{f[i-1][v][u],f[i-1][v-a[i]][u-b[i]]+w[i]}
二维费用背包降维
但是,我们可以把上述的i维(描述物品的维数抽掉,仅保留二维费用v,u),达到降维目的。针对本题,我们有两种选择:
v代表花费的时间,u代表花费的件数
v代表花费的件数,u代表花费的时间
这两者没用实质上的区别,区别的地方在于初始化dp时的方式不同。
回顾题目,我们发现:店家只卖M张碟。也就是说,在件数这个维度上,我们必须达到M维,多不行,少也不行,也就是我们常说的“刚好装满背包”。不过,对于时间维度L,最后看完M张碟的时间<=L就可以了。
当我们选择方式1:v代表花费的时间,u代表花费的件数时:
为了让u维(件数维)刚好装满,我们需要初始化dp[][]矩阵的第一列为0,其他列为-INF.
当我们选择方式2:v代表花费的件数,u代表花费的时间:
为了让v维(件数维)刚好装满,我们需要初始化dp[][]矩阵的第一行为0,其他行为-INF.
AC代码
初始化方式:v代表花费的件数,u代表花费的时间
按照0-1背包的特点,我们需要逆序遍历“件数”维和“时间维”,笔者试过4种dp转移方式(按照该初始化方式,共8种转移方式:2维循环嵌套 * v维2种遍历方式(小到大,大到小) * u维2种遍历方式(小到大,大到小)),其中有的不满足逆序遍历的方式也能AC,笔者对此比较疑惑,望知道的朋友告知。#include <iostream> #include <algorithm> #include <vector> #include <stack> #include <string> #include <cmath> #include <cstring> using namespace std; const int INF = 0x3F3F3F3F; const int MAXN = 105; int dp[105][1005]; int t[105], v[105]; int main() { int T; scanf("%d", &T); while (T--) { int N, M, L; scanf("%d%d%d", &N, &M, &L); for (int i = 1; i <= N; i++) scanf("%d%d", &t[i], &v[i]); /*for (int i = 0; i <= M; i++) { for (int j = 0; j <= L; j++) { if (i == 0) dp[i][j] = 0; else dp[i][j] = -INF; } }*/ memset(dp,-INF, sizeof(dp)); for (int i = 0; i <= L; i++)dp[0][i] = 0; for (int i = 1; i <= N; i++) { /*for (int j = L; j >= t[i]; j--) { //OK for (int k = 1; k <= M; k++) { dp[k][j] = max(dp[k][j], dp[k-1][j-t[i]]+v[i]); } }*/ /*for (int j = L; j >= t[i]; j--) { //OK for (int k = M; k >= 1; k--) { dp[k][j] = max(dp[k][j], dp[k - 1][j - t[i]] + v[i]); } }*/ for (int k = M; k >= 1; k--) { //OK for (int j = L; j >= t[i]; j--) { dp[k][j] = max(dp[k][j], dp[k - 1][j - t[i]] + v[i]); } } /*for (int k = 1; k <= M; k++) { // WA for (int j = L; j >= t[i]; j--) { dp[k][j] = max(dp[k][j], dp[k - 1][j - t[i]] + v[i]); } }*/ } cout << (dp[M][L] > 0 ? dp[M][L] : 0) << endl; } return 0; }
初始化方式:v代表花费的时间,u代表花费的件数
这种方式下没有测试各种转移方式,直接采用逆序遍历二维费用。有兴趣的可以试试其它转移方式,猜想和第一种初始化方式差不多:有的可以AC。#include <iostream> #include <string.h> using namespace std; const int INF = 0X3F3F3F3F; const int MAXN = 105; int c[MAXN]; int v[MAXN]; int dp[1005][105]; int main() { int t; scanf("%d", &t); while(t--) { int N, M, L; scanf("%d%d%d", &N, &M, &L); for(int i = 1; i <= N; ++i) { scanf("%d%d", &c[i], &v[i]); } memset(dp, -INF, sizeof(dp)); for(int i = 0; i <= L; ++i) { dp[i][0] = 0; } for (int i = 1; i b394 <= N; ++i) { for(int j = L; j >= c[i]; j--) { for (int k = M; k >= 1; --k) { dp[j][k] = max(dp[j][k], dp[j-c[i]][k-1]+v[i]); } } } if(dp[L][M] > 0) cout << dp[L][M] << endl; else cout << 0 << endl; } return 0; }
相关文章推荐
- HDOJ题目2660 Accepted Necklace(二维01背包)
- hdu 3496 Watch The Movie(二维01背包)
- POJ 1948 Triangular Pastures (二维01背包)
- hdu 3496 Watch The Movie(二维01背包)
- POJ - 1837 Balance 天平(二维01背包)
- HDU 3496 Watch The Movie (二维背包+01背包)
- poj1837Balance【二维01背包方法数——天平平衡】
- POJ2576 Tug of War (二维的01背包)
- poj3260 平衡问题(二维01背包)
- hdu 2660 Accepted Necklace (二维01背包)
- uva 1213 sum of different primes 01背包(二维)
- poj 1948 Triangular Pastures(二维01背包)
- HDU3496:Watch The Movie(二维01背包)
- hdu3496 Watch The Movie(二维01背包)
- hdu 2126 Buy the souvenirs (二维01背包)
- 动态规划之 01背包(一维,二维)
- HDU3496:Watch The Movie(二维01背包)
- hdu 3496 Watch The Movie(二维01背包)
- HDU 3496 Watch The Movie(二维01背包)
- bailian4102:宠物小精灵之收服(二维费用的01背包)