前言
又是一道动态规划+滚动数组的题,代码采用了异或操作,来标明两行数据,即现在要求的dp和需要用到的上一组dp。AC一波~
一、题目
传送门
Sample Input 3 1 1 2 1 5 2 4 4 1 2 0 0 0 0
Sample Output 0.5000 0.2500
二、解决
之前也写过两道动态规划+滚动数组的题,再来一道!
1.分析
每组数据都是从1开始,即开始时必然经过1,则dp[0][0]=1.0。定义的dp[now][i]数组是指在当前状态(now即要求的状态),下第i个数出现的概率,本题中的滚动数组,使用到的数据就只有上一行和本行所以dp纵向宽度为2,过去和现在两种状态,而now^1,的结果就两种状态,0/1,这里也可以定义a=0,b=1表示两种状态,每进行完一次就交换a,b的值,贴一波代码~
2.代码
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double dp[2][220];
int main() {
int n,m,l,r;
while(~scanf("%d%d%d%d",&n,&m,&l,&r)) {
if(n==0&&m==0&&l==0&&r==0){
break;
}
memset(dp,0,sizeof(dp));
int now=0;
dp[0][0]=1.0;
while(m--) {
int t;
scanf("%d",&t);
for(int i=0; i<n; i++) {
dp[now^1][i]=dp[now][(i-t+n)%n]*0.5+dp[now][(i+t)%n]*0.5;
}
now^=1;
}
double ans=0;
for(int i=l-1; i<r; i++) {
ans+=dp[now][i];
}
printf("%.4lf\n",ans);
}
}
|