ErikTse Runtime

  • 首页 / Home
  • | 算法学习 / Algorithm
    • 所有 / All
    • 简单 / Easy
    • 中等 / Medium
    • 困难 / Hard
  • | 技术分享 / Technology
    • 所有 / All
    • 网络技术 / NetWork
    • 资源共享 / Resource
    • 项目实践 / Event
Keep Going.
温故而知新.
  1. 首页
  2. 算法学习
  3. 中等
  4. 正文

[Light OJ]Discovering Gold(期望DP)

2022年5月2日 1198点热度 0人点赞 0条评论

传送门:Discovering Gold | LightOJ

题目描述 / Problem

在一个一维数轴上,起始点为1,终点为N。

从起始点开始,每次可以掷骰子,等概率地往后走[1, 6]中的任意距离,如果下一个点超过了N,重新掷骰子,每个点有一个金币数a[i]。求到达终点的金币期望。

思路 / Thought

期望DP。

第一种思路,是对从起始点到达该点的概率进行dp,然后乘以各点的金币数就是期望。

从前往后就可以。

为什么乘以各点金币数呢?因为这里是对概率的dp,也就是说相当于到了第i个点dp[i]次。

代码一

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 107;
double dp[maxn];//dp[i] means the expectation of possibility from 1 to i
int a[maxn];//the gold on the Point[i]


void solve()
{
	int N;cin >> N;//there are N points on the array
	
	for(int i = 1;i <= N; ++ i)cin >> a[i];//input
	
	memset(dp, 0, sizeof(int) * (N + 1));//init the dp array
	dp[1] = 1.0;//init
	
	for(int i = 1;i <= N; ++ i)
	{
		int k = min(N - i, 6LL);//the possibilities you can go
		for(int j = 1;j <= k; ++ j)//jump j steps every time
			dp[i + j] += dp[i] * 1.0 / k;
	}
	double ans = 0;
	for(int i = 1;i <= N; ++ i)ans += dp[i] * a[i];
	cout << fixed << setprecision(6) << ans << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	int _;cin >> _;
	for(int i = 1;i <= _; ++ i)
	{
		cout << "Case " << i << ": "; 
		solve();
	}
	return 0;
}

第二种思路,从后往前DP,dp[i]表示从i走到N的金币期望,这里最后不需要计算概率因为概率为1。

状态转移方程:

代码二

#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
const int maxn = 109;
double dp[maxn];
int a[maxn];
int kase = 1;

void solve()
{
	int N;cin >> N;
	memset(dp, 0, sizeof(int) * (N + 1));
	
	for(int i = 1;i <= N; ++ i)scanf("%lld", a + i);
	
	for(int i = N;i >= 1; -- i)
	{
		dp[i] = a[i];
		int k = min(N - i, 6LL); //k表示可以往后走的格子数
		for(int j = 1;j <= k; ++ j)
			dp[i] += dp[i + j] * 1.0 / k;
	}
	printf("Case %lld: %lf\n",kase ++, dp[1]);
}

signed main()
{
	int T;cin >> T;
	while(T --)solve();	
	return 0;
}
本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: C++ DP 期望dp 算法竞赛
最后更新:2022年8月3日

Eriktse

19岁,性别未知,ACM-ICPC现役选手,ICPC亚洲区域赛银牌选手,CCPC某省赛铜牌蒟蒻,武汉某院校计算机科学与技术专业本科在读。

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

订阅本站
Loading
文章目录
  • 题目描述 / Problem
  • 思路 / Thought

COPYRIGHT © 2022 ErikTse Runtime. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

赣ICP备2022001555号-1

赣公网安备 36092402000057号