LightOJ - 1079 (概率?DP!01背包中量的选择)

题意:

  有一个概率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\n",tt,i);
                break;
            }
        }
    }
    return 0;
}
View Code

 

  

posted @ 2020-03-09 22:19  dialectics  阅读(193)  评论(0编辑  收藏  举报