DP背包问题-套

0-1背包

Bessie has gone to the mall’s jewelry store and spies a charm bracelet. Of course, she’d like to fill it with the best charms possible from the N (1 ≤ N ≤ 3,402) available charms. Each charm i in the supplied list has a weight Wi (1 ≤ Wi ≤ 400), a ‘desirability’ factor Di (1 ≤ Di ≤ 100), and can be used at most once. Bessie can only support a charm bracelet whose weight is no more than M (1 ≤ M ≤ 12,880).Given that weight limit as a constraint and a list of the charms with their weights and desirability rating, deduce the maximum possible sum of ratings.Input* Line 1: Two space-separated integers: N and M

  • Lines 2…N+1: Line i+1 describes charm i with two space-separated integers: Wi and DiOutput* Line 1: A single integer that is the greatest sum of charm desirabilities that can be achieved given the weight constraints
    Sample Input
    4 6
    1 4
    2 6
    3 12
    2 7
    Sample Output
    23
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int T, M;
int f[1000005], a[4105], b[4105];
int main() {
    ios::sync_with_stdio(false);
    cin >> M >> T;
    for (int i = 0; i < M; i++) {
        cin >> a[i] >> b[i];
    }
    for (int i = 0; i < M; i++) {
        for (int j = T; j >= a[i]; j--) {
            if (j >= a[i]) {
                f[j] = max(f[j], f[j - a[i]] + b[i]);
            }
        }
    }
    cout << f[T] << endl;
    return 0;
}

完全背包
不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前.

死亡骑士:“我要买道具!”

地精商人:“我们这里有三种道具,血瓶150块一个,魔法药200块一个,无敌药水350块一个.”

死亡骑士:“好的,给我一个血瓶.”

说完他掏出那张N元的大钞递给地精商人.

地精商人:“我忘了提醒你了,我们这里没有找客人钱的习惯的,多的钱我们都当小费收了的,嘿嘿.”

死亡骑士:"…"

死亡骑士想,与其把钱当小费送个他还不如自己多买一点道具,反正以后都要买的,早点买了放在家里也好,但是要尽量少让他赚小费.

现在死亡骑士希望你能帮他计算一下,最少他要给地精商人多少小费.Input输入数据的第一行是一个整数T(1<=T<=100),代表测试数据的数量.然后是T行测试数据,每个测试数据只包含一个正整数N(1<=N<=10000),N代表死亡骑士手中钞票的面值.

注意:地精商店只有题中描述的三种道具.
Output对于每组测试数据,请你输出死亡骑士最少要浪费多少钱给地精商人作为小费.
Sample Input
2
900
250
Sample Output
0
50

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int f[1000005];
int k[3] = { 150,200,350 };
int main(){
	ios::sync_with_stdio(false);
	int n;
	cin >> n;
	while (n--) {
		int a;
		cin >> a;
		for (int i = 0; i < 3; i++) {
			for (int j = k[i]; j <= a; j++) {
				if (j >= k[i]) {
					f[j] = max(f[j], f[j - k[i]] + k[i]);
				}
			}
		}
		cout <<  a-f[a] << endl;
	}
	return 0;
}

多重背包
Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don’t know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
中文总结:分割,使的两部分的价值平均。若不能平均,要求差最小且大数在前输入Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 – the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
输出For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
样例输入
2
10 1
20 1
3
10 1
20 2
30 1
-1样例输出
20 10
40 40

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int v[1005], num[55];
int dp[100005];
int main(){
	std::ios::sync_with_stdio(false);
	int n;
	int sum;
	int cc;
	while (cin >> n ) {
		if (n < 0)break;
		sum = 0;
		memset(dp, 0, sizeof(dp));
		for (int i = 0; i < n; i++) {
			cin >> v[i] >> num[i];
			sum += (v[i] * num[i]);
		}
		cc = sum / 2;
		for (int i = 0; i < n; i++) {
			for (int k = 0; k < num[i]; k++) {
				for (int j = cc; j >= v[i]; j--) {
					dp[j] = max(dp[j], dp[j - v[i]] + v[i]);
				}
			}
		}
		cout << sum - dp[cc] << " " << dp[cc] << endl;
	}
}

急!灾区的食物依然短缺!
为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
请问:你用有限的资金最多能采购多少公斤粮食呢?

后记:
人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
感谢父母,他们给予我们生命,抚养我们成人;
感谢老师,他们授给我们知识,教我们做人
感谢朋友,他们让我们感受到世界的温暖;
感谢对手,他们令我们不断进取、努力。
同样,我们也要感谢痛苦与艰辛带给我们的财富~

Input输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。Output对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
Sample Input
1
8 2
2 100 4
4 100 2
Sample Output
400

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
int f[1000005], a[155], b[155], c[155];
int C, n, m;
int main() {
	ios::sync_with_stdio(false);
	cin >> C;
	while (C--) {
		cin >> n >> m;
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
		memset(f, 0, sizeof(f));
		for (int i = 0; i < m; i++) {
			cin >> a[i] >> b[i] >> c[i];
		}
		for (int i = 0; i <= m; i++) {
			for (int j = n; j >= 0; j--) {
				for (int k = 1; k <= c[i]; k++) {
					if (j >= a[i] * k) f[j] = max(f[j], f[j - a[i] * k] + b[i] * k);
				}
			}		
		}
		cout << f[n] << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值