1. 程式人生 > >51nod 1450 闖關遊戲——期望dp

51nod 1450 闖關遊戲——期望dp

tdi def () for inf stdout i++ ostream 排序。

題目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1450

想了半天,不知道不能走的狀態(即最後不足m個的狀態)怎麽辦。去吃晚飯的路上想到那種也是轉移到 f[ i ][ j ] 自己,因為意義是需要再來一次,狀態沒有前進。

想出那個之前稍微看了點題解,不過只看到需要按 y 排序。若非此自己可能還想不到要排序。還對拍驗證了一下,確實有差異。

把 y 大的排在前面,x 值大是第二關鍵字。之所以排在前面,是因為前面的影響更大(即使是倒著推的),就想搜索的時候把分叉少的排在前面一樣。

#include<iostream>
#include
<cstdio> #include<cstring> #include<algorithm> #define db double using namespace std; const int N=2005; const db INF=0x3f3f3f3f; int n,m; db f[N][N<<1]; struct Node{ db x,y,z; }a[N]; bool cmp(Node u,Node v){return u.y==v.y?u.x<v.x:u.y<v.y;} int rdn() { int ret=0,fx=1; char
ch=getchar(); while(ch>9||ch<0){ if(ch==-) fx=-1; ch=getchar();} while(ch>=0&&ch<=9) ret=(ret<<3)+(ret<<1)+ch-0,ch=getchar(); return ret; } int main() { // freopen("51nod1450-data.in","r",stdin); // freopen("51nod1450-bl.out","w",stdout); n=rdn(); m=rdn();
for(int i=1;i<=n;i++) a[i].x=(db)rdn()/1000,a[i].y=(db)rdn()/1000,a[i].z=1-a[i].x-a[i].y; sort(a+1,a+n+1,cmp); for(int i=0;i<m;i++) f[n+1][i]=INF; for(int i=m,d=((n+1)<<1);i<=d;i++) f[n+1][i]=0; for(int i=n;i;i--) for(int j=0,d=(i<<1);j<=d;j++) { // printf("i=%d j=%d\n",i,j); // printf("f[i+1][j+1]=%.8lf f[i+1][j+2]=%.8lf\n",f[i+1][j+1],f[i+1][j+2]); if(f[i+1][j+1]==INF) { if(f[i+1][j+2]==INF) f[i][j]=INF; else f[i][j]=(a[i].y*f[i+1][j+2]+1)/(1-a[i].x-a[i].z); } else f[i][j]=(a[i].x*f[i+1][j+1]+a[i].y*f[i+1][j+2]+1)/(1-a[i].z); // printf("f[%d][%d]=%.8lf\n",i,j,f[i][j]); } printf("%.8lf\n",f[1][0]); return 0; }

51nod 1450 闖關遊戲——期望dp