hiho1091_clicker背包问题

问题

    类似有限背包问题,题目链接:clicker

实现

#include<stdio.h>
#include<cmath>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<deque>
#include<string>
#include<unordered_map>
#include<unordered_set>
using namespace std;

#define max(a, b) (a) > (b)? (a) : (b)
int dp[35][20005];
int A[35];
int B[35];
int main() {
	int n, m;
	scanf("%d %d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d %d", &A[i], &B[i]);
	}
	memset(dp, 0, sizeof(dp));
	//有限背包问题, dp[i][j] 表示对于前i种物品,耗费j时能够得到的最大收益
	for (int i = 1; i <= n; i++) { //dp的定义,前i种物品的收益情况,依赖于前i-1种物品的情况。 i表示前i种物品
		for (int j = 0; j <= m; j++) { //耗费为j,这里j从小到大枚举和从大到小枚举都行,因为 
			//根据递推公式: dp[i][j] = max(dp[i][j], dp[i - 1][j - cost] + k*A[i - 1]); dp[i][j] 和 dp[i-1][jj]有关,
			//而在内层循环的j的枚举方向不会影响结果正确性(如果 dp[i][j] 和 dp[i][jj] (jj为大于或者小于j的数)有关,则会影响)
			int k = 1;
			int t = B[i - 1];
			int cost = t;
			dp[i][j] = max(dp[i][j], dp[i - 1][j]); //第i种一个都不要
			while (cost <= j) { //依次枚举第i种物品的个数
				dp[i][j] = max(dp[i][j], dp[i - 1][j - cost] + k*A[i - 1]);
				t *= 1.07;
				cost += int(t);
				k++;
			}	
		}
	}
	printf("%d
", dp[n][m]);
	return 0;
}
原文地址:https://www.cnblogs.com/gtarcoder/p/5593343.html