/* 以下分析有参考Baidu 的,刚开始学背包,感觉不顺手啊。 二维的完全背包,状态转移方程:dp[i][j] = max(dp[i][j], dp[i - df[t].care][j - 1] + df[t].expr) dp[i][j] 消耗i的忍耐度获得的最大经验值,只要dp[i][s] >= n 就可以找到答案 dp[i][j]表示杀i个怪剩j忍耐值获得的最大经验值 状态方程:dp[i][j] = max(dp[i][j], dp[i - 1][j - df[t].care] + df[t].expr) 结果为m - j 其中j为 dp[s][j] >= n (1 <= j <= m)而且j最小 */ #include <iostream> #include <cstdio> #include <algorithm> using namespace std; struct node { int expr; int care; }df[105]; int dp[105][105]; int main() { int n, m, k, s; while(cin >> n >> m >> k >> s) { for(int i = 1; i <= k ; i++) cin>>df[i].expr >> df[i].care; memset(dp, 0, sizeof(dp)); int jj = -1; int i, j, t; /* for(i = 1; i <= m; i++) { for(j = 1; j <= s; j++) for(t = 1; t <= k; t++) if(i >= df[t].care) dp[i][j] = max(dp[i][j], dp[i - df[t].care][j - 1] + df[t].expr); if(dp[i][s] >= n) { jj = i; break; //goto loop; } } */ for(i = 1; i <= s; i++) { for(j = 1; j <= m; j++) for(t = 1; t <= k; t++) if(j >= df[t].care) dp[i][j] = max(dp[i][j], dp[i - 1][j - df[t].care] + df[t].expr); for(int j = 1; j <= m; j++) if(dp[s][j] >= n) { jj = j; //break; goto loop; } } loop: if(jj == -1) printf("%d/n", jj); else printf("%d/n", m - jj); } }