题目链接:https://vjudge.net/problem/Gym-101190F
题意:一开始共有n个卡片,C代表摆放正确,W代表摆放错误,每次可以选取前k张卡片,如果这k张卡片中的第一张是W,则将这k张卡片全部翻转后放在桌面上(翻转即C变W,W变C),如果第一张是C则不进行任何操作直接将这k张卡片放在桌面上,然后再在剩下的卡片中重复进行上述操作,直至所有卡片都放在桌面上了。求最终桌面上W个数的期望值。
思路:场上看出来是概率DP,但是不会推状态就去搞模拟了,看了题解的状态后自己推公式也能推出来,但是最难得还是如何找状态,DP学习很难一蹴而就,得经常联系培养思维才行。设P[i]为第i张牌作为k张牌中的第一张牌的可能性,p[0] = 1(第一张牌在第一次操作时一定是首张牌),p[i] = 1.0 / (n - i + 1.0),i >= 1。这个仔细退一下不难发现,我推到i=3发现的规律。设dp[i][0]代表第i张牌不翻转的概率,dp[i][1]代表第i张牌翻转的概率。最后对所有卡片为W的概率求和即可。如果s[i] == 'C', ans += dp[i][1](第i张卡片翻转后才能变成W), 否则ans += dp[i][0](第i张卡片起初就是W,故不需要翻转)。推状态转移方程时,只要考虑i和i-1即可。每张牌要么翻转要么不翻转,故dp[i][0] + dp[i][1] = 1,本来以为求出dp[i][0],直接用1-dp[i][0]求得dp[i][1]即可,但是可能是精度卡的太严的原因吧会Wrong Answer in Test 27,后来用状态转移公式求dp[i][1],就过了。看了RX的代码更加神奇,他写的用if else过不了,用三目运算符就能够。个人觉得是精度问题,但是我实在看不出他的两种写法有什么区别。RX的博客:http://blog.csdn.net/kim0403/article/details/77685142 dp状态转移方程详细见代码。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include