题意:
有一个概率Q,Q的初始值为1,一个界限P,以及N件物品,每件物品都有自身的价值vi,以及一个概率下降比率pi(表示选取这件物品会导致Q变为 Q*(1-pi))。
问在Q大于P的条件下,最大的收益值。
核心思想:01背包的思想,选取正确的 量 作为背包容量。
题解思路:
如果以概率作为‘背包容量’,因为概率是个连续变化量,所以DP【i】【1~+∞】,不可取。
固选择收益作为‘背包容量’,选择概率作为‘背包收益’,DP[i][j]实际意义:面对前i件物品,收益 大于等于 j时的最大概率。(模型意义:背包容量为j时的最大收益,但模型意义对这题不太相符,因为允许重量大于容量,即模型意义不能很好的解决这个问题,亦可以理解为一般的DP,而不必局限于背包模型)。
状态转移方程:
最终选取使DP[n][j]>=P的最大j。
收获:
01背包模型中容量与价值可以根据实际情况选择相应的量,容量一定在计算时间内可穷。
模型终归是模型,遇到具体问题时应学会合理变化与使用模型,不可局限于模型。
#include <iostream> #include <cstring> using namespace std; const int MAXN=1e4+10; int weight[101]; double value[101]; double dp[MAXN]; int N; double P; int main() { int T; scanf("%d", &T); for (int tt = 1; tt <= T; tt++) { memset(dp, 0, sizeof(dp)); scanf("%lf%d",&P,&N); dp[0]=1; int sum=0; for(int i=1;i<=N;i++){ scanf("%d%lf",weight+i,value+i); sum+=weight[i]; } for(int i=1;i<=N;i++){ for(int j=sum;j>=weight[i];j--){ dp[j]=max(dp[j],dp[j-weight[i]]*(1-value[i])); } } for(int i=sum;i>=0;i--){ if(dp[i]>=(1-P)){ printf("Case %d: %d ",tt,i); break; } } } return 0; }