思路:题意就是小明去买东西,每个物品呢可以用钱购买,也可以用积分换,总共小明也有免费获得物品的次数k次(也就是可以免费获得k个物品);
所以最后的决策就是是用钱买,还是用积分换,还是用免费领取的次数;
这里的01背包和我以前写的方式有点不同就是,,,这个继承上一个状态的写法;
以前是倒着写的,由于这里for层数较多,,,所以就换了个写法;
点击打开链接
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; #define MEM(a,b) memset(a,b,sizeof a) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long ll; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int dp[102][102][102][7]; int n,v1,v2,fee; int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d%d%d",&n,&v1,&v2,&fee)){ MEM(dp, 0); for (int i = 1;i <= n;++i){ int a,b,val;//价钱,所需积分,实际价值 // cin >> a >> b >> val; scanf("%d%d%d",&a,&b,&val); for (int j = 0;j <= v1;j++){ for (int k = 0;k <= v2;++k){ for (int t = 0;t <= fee;++t){ dp[i][j][k][t] = dp[i - 1][j][k][t];//不选第i件物品; if (t >= 1) dp[i][j][k][t] = Get_Max(dp[i][j][k][t],dp[i - 1][j][k][t - 1] + val); if (k - b >= 0) dp[i][j][k][t] = Get_Max(dp[i][j][k][t],dp[i - 1][j][k - b][t] + val); if (j - a >= 0) dp[i][j][k][t] = Get_Max(dp[i][j][k][t],dp[i - 1][j - a][k][t] + val); } } } } // cout << dp[n][v1][v2][fee] << '\n'; printf("%d\n",dp[n][v1][v2][fee]); } return 0; }