題意:
n個對象,每價值爲vi,比重pi,總容量100
分析:
類似揹包重量的比重pi爲實數,不能作爲下標,所以改變dp對象
將求容量100內的最大價值 → 求相應價值的最小容量,
則容量第一個≤100的價值,爲符合條件的價值最大的值
狀態:dp[v]:價值爲v的最小容積
轉移方程:
dp[V] = min(dp[V], dp[V-v[i]] + p[i]);
核心:
for(i = 1; i<=n; i++) { for(j = sum_V; j>=v[i]; j--) { dp[j] = min(dp[j], dp[j-v[i]] + p[i]); } }
代碼:
#include <stdio.h> #include <iostream> #include <math.h> #include <algorithm> #include <string.h> #include <string> #include <queue> #include <stack> #include <map> #include <vector> #include <time.h> using namespace std; double p[1000+10]; int v[1000+10]; double dp[5*1000+10]; int main() { //freopen("a.txt", "r", stdin); int n, i, j; while(~scanf("%d", &n)) { int sum = 0; for(i = 1; i<=n; i++) { scanf("%lf%d", &p[i], &v[i]); sum += v[i]; } memset(dp, 0x4f, sizeof(dp)); dp[0] = 0; for(i = 1; i<=n; i++) { for(j = sum; j>=v[i]; j--) { dp[j] = min(dp[j], dp[j-v[i]] + p[i]); } } while(dp[sum]>100)sum--; printf("%d\n", sum); } return 0; }