两道题都是01背包的入门题。共同点:求放入背包物品的最小值。区别:前者的容量有下限(这和一般的背包相反)。
有一个tip:使用memset函数要注意,它并不是简单的初始化,慎用。
HOJ1215
转化为求”使得血量达到100所消耗分数的最小值“
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX = 10010;
int dp[10020];
int main()
{
int t;
scanf("%d", &t);
while(t--){
int hp;
scanf("%d", &hp);
int n, sum = 0;
scanf("%d", &n);
int c[10020], v[10200];
for(int i = 1; i <= n; i++){
scanf("%d %d", &c[i], &v[i]);
sum += v[i];
}
for(int i = 1; i <= MAX; i++) dp[i] = INF;
for(int i = 1; i <= n; i++)
for(int j = MAX; j >= c[i]; j--)
dp[j] = min(dp[j], dp[j - c[i]] + v[i]);
int res = INF;
for(int i = hp; i <= MAX; i++) res = min(res, dp[i]);
if(res == INF) res = 0;
else res = sum - res;
printf("%d\n", res);
}
return 0;
}
HDU1203
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF && (n || m)){
int c[10005];
double v[10005];
for(int i = 1; i <= m; i++){
scanf("%d %lf", &c[i], &v[i]);
v[i] = 1 - v[i];
}
double dp[10010];
for(int i = 0; i <= 10005; i++) dp[i] = 1;
for(int i = 1; i <= m; i++)
for(int j = n; j >= c[i]; j--)
dp[j] = min(dp[j], dp[j - c[i]] * v[i]);
printf("%.1lf", 100 * (1 - dp[n]));
puts("%");
}
return 0;
}