NKOJ 打氣球【期望概率DP】
阿新 • • 發佈:2018-11-08
很簡單啦,隨便寫寫然後記憶化實現一下就好了嘛:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define db double #define sg string #define ll long long #define rep(i,x,y) for(ll i=(x);i<=(y);i++) #define red(i,x,y) for(ll i=(x);i>=(y);i--) using namespace std; const ll N=2e3+5; db f[N][N]; ll n,m,row[N],col[N]; inline ll read() { ll x=0;char ch=getchar();bool f=0; while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?-x:x; } void dfs(ll c,ll r ){ if(f[c][r]!=-1) return ; if(!c&&!r) { f[c][r]=0.0;return ; } db ret=0.0; if(c) { dfs(c-1,r); ret+=(c*(n-r)*f[c-1][r]); } if(r) { dfs(c,r-1); ret+=(r*(n-c)*f[c][r-1]); } if(c&&r) { dfs(c-1,r-1); ret+=(c*r*f[c-1][r-1]); } f[c][r]=1.0*(ret*1.0+n*n)/(1.0*(c+r)*n-1.0*c*r); } void File() { freopen("shoot.in","r",stdin); freopen("shoot.out","w",stdout); } int main() { // File(); n=read(),m=read(); rep(i,1,m) { ll x=read(),y=read(); col[x]=1,row[y]=1; } ll c=0,r=0; rep(i,1,n) if(!col[i]) c++; rep(i,1,n) if(!row[i]) r++; rep(i,0,n) rep(j,0,n) f[i][j]=-1.0; dfs(c,r); printf("%.2lf",f[c][r]); return 0; }