DP 動態規劃 Problem V 1022 反向考慮的揹包
Problem V ID:1022
簡單題意:某人準備搶銀行,可以承受的最大被抓的概率為p(總共),共有n個銀行可搶,分別給出各個銀行所擁有的money:mi,搶各個銀行被抓的概率pi。求可以搶到的最大金額。
解題思路形成過程:因為概率值的範圍為0~1,即有小數,所以必須反向來考慮。
可以承受的最大被抓的概率為p,即:如果逃跑的概率大於1-p則符合要求。
將所有銀行的總錢數作為揹包的容量,dp陣列各元素對應的值為逃跑的概率。
如果搶兩個銀行i和j,則逃跑概率為(1-pi)*(1-pj),即兩個銀行逃跑的概率之積。(涉及到概率論)
狀態轉移方程為:dp[j]=max(dp[j],dp[j-a[i]]*(1-b[i]));
dp陣列中逃跑率符合要求且下標最大的一個所對應的下標即為所求答案。
感想:一開始被樣例給帶跑偏了,還以為會出現的概率是精確到小數點後兩位的,而實際上並不是。這就決定了很難用常用的揹包思想去解決這個問題。
要學會去反向思考,要求是被抓的概率要符合要求,那逃跑的概率符合要求是否可以?dp陣列要存的元素能不能存經常存的下標?
程式碼:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
double dp[10001];
int a[101];
double b[101];
int main()
{
//freopen("1.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
double p;
int n,sum=0;
scanf("%lf%d",&p,&n);
for(int i=0; i<n; ++i)
{
scanf("%d%lf",&a[i],&b[i]);
sum+=a[i];
}
dp[0]=1;
for(int i=0; i<n; ++i)
for(int j=sum; j>=a[i]; --j)
dp[j]=max(dp[j],dp[j-a[i]]*(1-b[i]));
for(int i=sum; i>=0; --i)
{
if(dp[i]>1-p)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}
相關文章
- 【動態規劃】揹包問題動態規劃
- 揹包問題----動態規劃動態規劃
- 動態規劃 01揹包問題動態規劃
- 【動態規劃】01揹包問題動態規劃
- 動態規劃--01揹包問題動態規劃
- 動態規劃篇——揹包問題動態規劃
- 動態規劃-01揹包問題動態規劃
- 【動態規劃】01揹包問題【續】動態規劃
- 演算法-動態規劃-完全揹包演算法動態規劃
- 動態規劃(DP)動態規劃
- 0-1揹包問題(動態規劃)動態規劃
- 01揹包動態規劃空間優化動態規劃優化
- 多重揹包動態規劃及空間優化動態規劃優化
- 動態規劃之0,1揹包問題動態規劃
- 動態規劃解0-1揹包問題動態規劃
- 動態規劃系列之六01揹包問題動態規劃
- 揹包DP——完全揹包
- 揹包DP——混合揹包
- 動態規劃-揹包01問題推理與實踐動態規劃
- 01揹包問題理解動態規劃演算法動態規劃演算法
- [動態規劃] 區間 dp動態規劃
- (C++)DP動態規劃C++動態規劃
- DP動態規劃-爬塔(雙層dp)動態規劃
- 揹包DP
- 詳解動態規劃01揹包問題--JavaScript實現動態規劃JavaScript
- 詳解動態規劃01揹包問題–JavaScript實現動態規劃JavaScript
- 動態規劃之 0-1 揹包問題詳解動態規劃
- 【動態規劃】一次搞定三種揹包問題動態規劃
- 動態規劃篇——線性DP動態規劃
- 【動態規劃】0-1揹包問題原理和實現動態規劃
- python 動態規劃(揹包問題和最長公共子串)Python動態規劃
- dp-完全揹包
- 動態規劃 區間dp 基礎題動態規劃
- 【動態規劃】樹形DP完全詳解!動態規劃
- DP 動態規劃入門 一維陣列動態規劃陣列
- 動態規劃演算法(DP)學習<1>動態規劃演算法
- 動態規劃入門——動態規劃與資料結構的結合,在樹上做DP動態規劃資料結構
- 【動態規劃】一些奇怪的DP題目的列表動態規劃
- 強化學習(三)用動態規劃(DP)求解強化學習動態規劃