POJ1644 DP+一些感悟

来源:互联网 发布:淘宝大学vip靠谱吗 编辑:程序博客网 时间:2024/05/29 18:05

题目描述

A chip is initially placed on the Start square. The player then tries to move the chip to the End square through a series of turns, at which point the game ends. In each turn a coin is fl
ipped: if the coin is heads the chip is moved one square to the right and if the coin is tails the chip is moved two squares to the right (unless the chip is one square away from the End square, in which case it just moves to the End square). At that point, any instruction on the square the coin lands on must be followed. Each instruction is one of the following:
1. Move right n squares (where n is some positive integer)
2. Move left n squares (where n is some positive integer)
3. Lose a turn
4. No instruction
After following the instruction, the turn ends and a new one begins. Note that the chip only follows the instruction on the square it lands on after the coin flip. If, for example, the chip lands on a square that instructs it to move 3 spaces to the left, the move is made, but the instruction on the resulting square is ignored and the turn ends. Gambling for this game proceeds as follows: given a board layout and an integer T, you must wager whether or not you think the game will end within T turns.
After losing his shirt and several other articles of clothing, Alexander has decided he needs professional help-not in beating his gambling addiction, but in writing a program to help decide how to bet in this game.

算法思路

  1. 这是一道很显然的DP题。
  2. 开始的时候,芯片一定会在0点,所以dp[0][0] = 1.0
  3. 如果在i时刻造成罚时,那么就相当于在i+1时刻到达了这个地点
  4. 如果需要转移,则相当于在i时刻到达了转移后的地点。
  5. 由于解空间的限制,我们最后转移的地点只可能是M+1,M+2,但是我们知道不能跑到终点以外,所以turn[M-1]=-1

一些问题

  1. 输入的问题,使用字符串输入,然后采用sscanf来扫描字符串
  2. 注意浮点数的精度
  3. 开始时采用从上像下转移,但是边界情况太多,后来改变转移方程取得了不错的效果。
  4. 看起来我还是弱渣。

代码

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;#define MAXM 55#define MAXT 45#define INF 100#define ZERO 10e-6double dp[MAXT][MAXM];int M,T,cas;int turn[MAXM];void Input(){    int i;    char com[5];    scanf("%d%d",&M,&T);    memset(turn,0,sizeof(turn));    for(i=1;i<=M;i++){        scanf("%s",com);        if(com[0] == 'L')            turn[i] = INF;        else             sscanf(com,"%d",&turn[i]);    }    turn[M+1] = 0;    turn[M+2] = -1;//  for(i=1;i<=M;i++)//      printf("%d ",turn[i]);//  printf("\n");}void Solve(){    int i,j;    double ans = 0;    memset(dp,0,sizeof(dp));    dp[0][0] = 1.0;    for(i=0;i<T;i++){        for(j=0;j<=M;j++){            if(turn[j+1] == INF)                dp[i+2][j+1] += 0.5*dp[i][j];            else                 dp[i+1][j+1+turn[j+1]] += 0.5*dp[i][j];            if(turn[j+2] == INF)                dp[i+2][j+2] += 0.5*dp[i][j];            else                 dp[i+1][j+2+turn[j+2]] += 0.5*dp[i][j];        }    }    for(i=0;i<=T;i++)        ans += dp[i][M+1];    if(ans < 0.5)        printf("Bet against. %.4f\n",ans);    else if(ans > 0.5)        printf("Bet for. %.4f\n",ans);    else         printf("Push. 0.5000\n");}int main(){    freopen("F.1.dat","r",stdin);    scanf("%d",&cas);    while(cas--){        Input();        Solve();    }}
0 0
原创粉丝点击