http://acm.hit.edu.cn/hoj/problem/view?id=1402
dp 崩溃了,这题做得,虽然是一次过的,但是写边界条件太麻烦了,测试了好久。状态方程很直接
/*This Code is Submitted by billforum for Problem 1402 at 2012-02-02 21:44:39*/
#include <iostream>
using namespace std;
int d[51][51]={0},s[51][51][51]={0},p[51][51],q[51][51];
int max(int x,int y)
{
return (x>y?x:y);
}
int main(int args,char** argv)
{
int n,k;
while(cin>>n>>k)
{
for(int i=1;i<=n;i++)
d[i][0]=0;
d[0][0]=1;
for(int i=0;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(j>i) d[i][j]=d[i][i];
else d[i][j]=d[i-j][j]+d[i][j-1];
}
for(int i=1;i<=n;i++)
s[i][1][i]=1;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(j>i) s[i][1][j]=s[i][1][i];
for(int i=1;i<=n;i++)
for(int j=2;j<=n;j++)
for(int t=1;t<=n;t++)
{
if(t>i) s[i][j][t]=s[i][j][i];
else s[i][j][t]=s[i-t][j-1][t]+s[i][j][t-1];
}
for(int i=1;i<=n;i++)
p[1][i]=1;
for(int i=1;i<=n;i++) p[0][i]=1;
for(int i=2;i<=n;i++)
for(int j=2;j<=n;j++)
if(i>=j) p[i][j]=p[i-j][j-1]+p[i][j-1];
else p[i][j]=p[i][i];
for(int i=1;(i%2==1)&&(i<=n);i=i+2)
q[0][i]=1;
q[0][0]=1;
for(int i=1;i<=n;i++)
q[i][1]=1;
for(int i=1;i<=n;i++)
for(int j=3;j<=n;j=j+2)
{
if(j>i)
{
if(i%2==1) q[i][j]=q[i][i];
else q[i][j]=q[i][i-1];
}
else q[i][j]=q[i-j][j]+q[i][j-2];
}
//if(n%2==1)
//cout<<q[n][n]<<endl;
//else cout<<q[n][n-1]<<endl;
//cout<<q[5][5];
cout<<d[n][n]<<endl;
cout<<s[n][k][n]<<endl;
cout<<d[n][k]<<endl;
if(n%2==1)
cout<<q[n][n]<<endl;
else cout<<q[n][n-1]<<endl;
cout<<p[n][n]<<endl;
cout<<endl;
}
return 0;
}