0/1背包问题(待更新)

题目:Acwing2. 01背包问题
链接:https://www.acwing.com/problem/content/2/

思路:
在这里插入图片描述
AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 1005;

int n, V;
int v[maxn], w[maxn];
int f[maxn];

int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d", &n, &V);
	for(int i = 1; i <= n; i ++)
		scanf("%d%d", &v[i], &w[i]);
	
	for(int i = 1; i <= n; i ++)
		for(int j = V; j >= v[i]; j --) 
			f[j] = max(f[j], f[j - v[i]] + w[i]);

	printf("%d\n", f[V]);
	
//	fclose(stdin);
	return 0;
} 

题目:Acwing423. 采药
链接:https://www.acwing.com/problem/content/425/

思路:
在这里插入图片描述
AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 105;

int T, M;
int t[maxn], w[maxn];
int f[1005];


int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d", &T, &M);
	for(int i = 1; i <= M; i ++)
		scanf("%d%d", &t[i], &w[i]);
		
	for(int i = 1; i <= M; i ++)
		for(int j = T; j >= t[i]; j --)
			f[j] = max(f[j], f[j - t[i]] + w[i]);
		
	printf("%d\n", f[T]);
	
//	fclose(stdin);
	return 0;
}

题目:Acwing426. 开心的金明
题目链接:https://www.acwing.com/problem/content/428/

思路:
在这里插入图片描述
AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 30;

int n, m;
int money[maxn], w[maxn];
int f[30005];

int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i ++)
		scanf("%d%d", &money[i], &w[i]);
	
	for(int i = 1; i <= m; i ++)
		for(int j = n; j >= money[i]; j --)
			f[j] = max(f[j], f[j - money[i]] + money[i] * w[i]);
			
	printf("%d\n", f[n]);
	
//	fclose(stdin);
	return 0;
}

题目:Acwing1022. 宠物小精灵之收服
题目链接:https://www.acwing.com/problem/content/1024/
思路:
在这里插入图片描述
AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

int n, m, k;
int c_n[105], c_b[105];
int f[505][1005], vis[505][1005];

int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= k; i ++)
		scanf("%d%d", &c_n[i], &c_b[i]);

	for(int i = 1; i <= k; i ++) //精灵种类 
		for(int j = m; j >= c_b[i]; j --)   //消耗的体力 
			for(int cnt = n; cnt >= c_n[i]; cnt --)   //消耗的精灵球
				if(f[j - c_b[i]][cnt - c_n[i]] + 1 > f[j][cnt]) {
					f[j][cnt] = f[j - c_b[i]][cnt - c_n[i]] + 1;
					vis[j][cnt] = vis[j - c_b[i]][cnt - c_n[i]] + c_b[i];
				} else if(f[j - c_b[i]][cnt - c_n[i]] + 1 == f[j][cnt]) {
					vis[j][cnt] = min(vis[j - c_b[i]][cnt - c_n[i]] + c_b[i], vis[j][cnt]);
				}
				 
	printf("%d %d\n", f[m][n], m - vis[m][n]);
	
//	fclose(stdin);
	return 0;;
}

题目:Acwing1024. 装箱问题
题目链接:https://www.acwing.com/problem/content/1026/

相当于把体积数组和价值数组合成了一个数组

AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

int V, n;
int v[35];
int f[20005];

int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d", &V, &n);
	for(int i = 1; i <= n; i ++) scanf("%d", &v[i]);
	
	for(int i = 1; i <= n; i ++)
		for(int j = V; j >= v[i]; j --)
			f[j] = max(f[j], f[j - v[i]] + v[i]);
		
	printf("%d\n", V - f[V]);
	
//	fclose(stdin);
	return 0;
}

题目:Acwing7. 混合背包问题
题目链接:https://www.acwing.com/problem/content/7/

思路:
遇到了完全背包和01背包的时候就照常就可以了,但是这道题目我们需要优化一下多重背包的时间复杂度,这李我用的是二进制优化,降了一维的时间复杂度
注意点:
1.数组要开的足够大

AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 1e4 + 5;

int N, V;
int v[maxn], w[maxn], id[maxn];
int f[maxn][1005];
int cnt;

int main(void) {
//	freopen("in.txt", "r", stdin);
	scanf("%d%d", &N, &V);
	for(int i = 1; i <= N; i ++)
		scanf("%d%d%d", &v[i], &w[i], &id[i]);
	cnt = N;
		
	for(int i = 1; i <= N; i ++) 
		if(id[i] > 0) {
			int s = id[i], k = 1;
			
			while(k <= s) {
				cnt ++;
				v[cnt] = k * v[i];
				w[cnt] = k * w[i];
				id[cnt] = -1;
				s -= k;
				k <<= 1;
			}
			
			if(s) {
				cnt ++;
				v[cnt] = s * v[i];
				w[cnt] = s * w[i];
				id[cnt] = -1;
			}
		}
	 
	N = cnt;
	for(int i = 1; i <= N; i ++)
		for(int j = 1; j <= V; j ++) {
			int idd = id[i];
			if(idd == -1) {
				f[i][j] = f[i - 1][j];
				if(j >= v[i]) f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
			} else if(idd == 0) {	
				f[i][j] = f[i - 1][j];
				if(j - v[i] >= 0) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
			} else f[i][j] = f[i - 1][j];
		}

	printf("%d\n", f[N][V]);
	
//	fclose(stdin);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值