这个周刷了很多概率期望有关的dp题目,缘起2016青岛D题和取log的神操作题HDU 5988 2016青岛区域赛 (最小费用流)
这类题目没有固定的模板,而且概率可以很容易插入一些经典模型,比如下面的 TSP。最小费用流。
我刷的这部分题目,无一例外均可用dp解决,主要是找到状态,很多题目都可以抽象成马尔科夫链
下面记录一下刷的经典题目
B - Discovering Gold
一排1到n的格子,每个格子上有黄金 ai ,你最开始在 1 号,每一次投塞子决定到哪一个格子,不能超出范围,你到了哪个格子就得到哪个格子的金币,问最终在
思路
在第 i 个格子能转移到
code
#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define ms(x,v) memset((x),(v),sizeof(x))
#define scint(x) scanf("%d",&x );
#define scf(x) scanf("%lf",&x );
#define eps 1e-10
#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))
#define lc o<<1
#define rc o<<1|1
using namespace std;
typedef long long LL;
typedef long double DB;
typedef pair<int,int> Pair;
const int maxn = 100+10;
const int MAX_V= 500+10;
const int MOD = 998244353;
double dp[maxn];
int a[maxn];
int main()
{
// ios_base::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int T;
cin>>T;
int kase =0;
while (T--) {
int n;
cin>>n;
ms(dp,0);
double ans =0;
for(int i =1 ; i<=n ; ++i)cin>>a[i];
dp[1] = 1;
for(int i=1 ; i <= n ; ++i){
int k = min(6,n-i);
for(int j =1 ; j<=k ; ++j)dp[j+i]+= dp[i]/k;
}
for(int i=1 ; i<=n ; ++i){
ans += dp[i]*a[i];
}
printf("Case %d: %.9lf\n",++kase, ans);
}
//std::cout << "time "<< clock()/1000 <<"ms"<< '\n';
return 0;
}
Island of Survival
(感谢A_LeiQ)翻译
被拉去参加一个野外求生……姑且这么叫吧。
岛上有t只老虎(T)和d只熊(D)还有自己(M)。每天会有两只生物相遇(自己也算)
T-M T会吃掉M
T-D T会吃掉D
D-D Nothing
M-D M可以选择杀与不杀D
T-T 两只T会互相残杀(Two Die)
问最终人类可以存货的概率(人类存活是指老虎都死光)
思路
这个问题其实很简单,遇到deer 不杀就行了,简单的想就是,杀了熊以后,老虎遇到你的概率就更大了,
设 dp[i][j 表示剩余 i老虎,j deer 时存活概率,用以上情况简单递推就好
#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define PI acos(-1)
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define INF64 0x3f3f3f3f3f3f3f3f
#define