HDU 2955 Robberies
一道变形的01背包,起初我脑残地将总概率乘100作为最大背包容量,对洗劫每个银行被抓的概率乘100视作物品体积进行dp,结果wa了好几次
后来知道这类问题一般不这么操作的,子状态存的是概率而不是物品总数
所以获得方程:dp[j] = max(dp[j], dp[V-c[i]]*(1-p[i]))
dp[j]: 偷得j件物品不被抓的概率,V: 最多可以抢劫的物品总数
其他还要注意初始化,dp[0] = 1,什么都不偷也就是不被抓
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 4 //dp[i]: 偷i件商品不被抓的概率 5 6 int main() 7 { 8 int t; 9 cin >> t; 10 while (t--) 11 { 12 int n, c[101], sum = 0; 13 double less, p[101], dp[10001] = {0}; 14 cin >> less >> n; 15 less = 1 - less; 16 for (int i = 0; i < n; i++) 17 { 18 cin >> c[i] >> p[i]; 19 sum += c[i]; 20 } 21 dp[0] = 1; //什么都不偷不会被抓 22 for (int i = 0; i < n; i++) 23 { 24 for (int j = sum; j >= c[i]; j--) 25 { 26 dp[j] = max(dp[j], dp[j-c[i]]*(1-p[i])); 27 } 28 } 29 for (int j = sum; j >= 0; j--) 30 { 31 if (dp[j] >= less) 32 { 33 cout << j << endl; 34 break; 35 } 36 } 37 } 38 return 0; 39 }