您的位置:首页 > 其它

USACO 2.3.2 Cow Pedigrees

2014-07-21 15:55 459 查看


标准DP题。

DP原理:

设某一节点下面的两子树的节点数加起来是x,两子树层数为y。

设x=nodes,y<=depth的方案数有f[nodes][depth]种,

x=nodes,y=depth的方案数有g[nodes][depth]种,

则f[nodes][depth]=g[nodes][0]+g[nodes][1]+.......+g[nodes][depth](1)

根据题意,记某一节点及其以下的节点共有DEP层,则它的两个子树至少有一个是DEP-1层。(红色部分特别容易被忽视!导致潜在的WA!苯渣的前九次WA就跪在这里T T)

所以,由容斥原理可以得到递推关系式:

g[nodes][depth]+=(f[i][depth-1]*g[nodes-2-i][depth-1]+g[i][depth-1]*f[nodes-2-i][depth-1]-g[i][depth-1]*g[nodes-2-i][depth-1])%MODULO(0<=i<=nodes-2,i是偶数);

此题中MODULO=9901。

/*
ID:szwjcch971
LANG:C++
TASK:nocows
*/
#include "stdio.h"
#include "string.h"
const int MODULO=9901;
int min(int a,int b){
return a<b?a:b;
}
int main(){
int f[205][105],g[205][105];
int i,j,I,J,N,K,l;
FILE *fin=fopen("nocows.in","r");
FILE *fout=fopen("nocows.out","w");
fscanf(fin,"%d%d",&N,&K);
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
g[0][0]=f[0][0]=1;
for(i=0;i<=104;i++)f[0][i]=1;
for(i=1;i<=104;i++)f[2][i]=1;
g[2][1]=f[2][1]=1;
g[2][0]=f[2][0]=0;
for(i=2;i<=(N-1)/2;i++){
for(j=1;j<=min(i,K-1);j++){
for(I=0;I<=i-1;I++){
g[2*i][j]+=(f[2*I][j-1]*g[2*i-2-2*I][j-1]+g[2*I][j-1]*f[2*i-2-2*I][j-1]-g[2*I][j-1]*g[2*i-2-2*I][j-1])%MODULO;
g[2*i][j]%=MODULO;
}
f[2*i][j]=(f[2*i][j-1]+g[2*i][j])%MODULO;
}
for(j=i+1;j<=K-1;j++)f[2*i][j]=f[2*i][i];
}
fprintf(fout,"%d\n",g[N-1][K-1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息