限制最多买n件物品的完全背包,二维的完全背包
定义dp[i][j]为最多i忍耐度,打j只怪能获得的最大经验
两种循环顺序都可以
需要注意的是:完全背包问题限制条件的维度和物品编号的维度的循环先后顺序是可以互换的.
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define INF 0x3f3f3f3f 6 #define MOD 1000000007 7 using namespace std; 8 typedef long long LL; 9 10 int ex, pat, kind, num; 11 const int maxn = 1e2 + 5; 12 int dp[maxn][maxn]; 13 int gt[maxn], lose[maxn]; 14 15 void solve() { 16 memset(dp, 0, sizeof(dp)); 17 for (int k = 0; k < kind; k++) { 18 for (int i = lose[k]; i <= pat; i++) { 19 for (int j = 1; j <= num; j++) { 20 dp[i][j] = max(dp[i][j], dp[i - lose[k]][j - 1] + gt[k]); 21 } 22 } 23 } 24 /* 25 for (int i = 1; i <= pat; i++) { 26 for (int k = 0; k < kind; k++) { 27 for (int j = 1; j <= num; j++) { 28 if (i >= lose[k]) 29 dp[i][j] = max(dp[i - lose[k]][j - 1] + gt[k], dp[i][j]); 30 } 31 } 32 } 33 */ 34 int i; 35 for (i = 1; i <= pat; i++) { 36 if (dp[i][num] >= ex) { 37 printf("%d ", pat - i); 38 break; 39 } 40 } 41 if (i == pat + 1) puts("-1"); 42 } 43 44 45 int main(int argc, const char * argv[]) { 46 while (~scanf("%d%d%d%d", &ex, &pat, &kind, &num)) { 47 for (int i = 0; i < kind; i++) { 48 scanf("%d%d", >[i], &lose[i]); 49 } 50 solve(); 51 } 52 return 0; 53 }