Acwing_1023. 买书_多重背包

题目链接:https://www.acwing.com/problem/content/1025/

DP思路:
/*
f[i, j]:从1 - i中取选择,然后一共只有j元钱,属性是count;钱可以不用完
1.不选第i本书籍:f[i - 1, j]
2.选择第i本书籍:f[i - 1, j - v], f[i - 1, j - 2 * v] -> f[]
*/

初始版代码:

#include <iostream>
#include <cstdio>

using namespace std;

int a[10];
int f[10][1005];

int main(void) {
	int n;  scanf("%d", &n);
	a[1] = 10, a[2] = 20, a[3] = 50, a[4] = 100;
	
	for(int i = 0; i <= 5; i ++) f[i][0] = 1;
	
	for(int i = 1; i <= 4; i ++)	
		for(int j = 1; j <= n; j ++) {
			for(int k = 0; ; k ++) {
				if(k * a[i] > j) break;
				f[i][j] += f[i - 1][j - k * a[i]];
			}
		}
	
	printf("%d\n", f[4][n]);
	
	return 0;
}

加入滚动数组:
变化思路:
在这里插入图片描述

#include <iostream>
#include <cstdio>

using namespace std;

int a[10];
int f[1005];

int main(void) {
	int n;  scanf("%d", &n);
	a[1] = 10, a[2] = 20, a[3] = 50, a[4] = 100;
	
	f[0] = 1;
	
	for(int i = 1; i <= 4; i ++)
		for(int j = a[i]; j <= n; j ++)
			f[j] += f[j - a[i]];
	
	printf("%d\n", f[n]);
	
	return 0;
}
发布了136 篇原创文章 · 获赞 0 · 访问量 2956

猜你喜欢

转载自blog.csdn.net/weixin_42596275/article/details/104082624