http://acm.hdu.edu.cn/showproblem.php?pid=2512
// 1290997 2009-04-20 16:28:41 Accepted 2512 62MS 14012K 545 B C++ no way 
#include < iostream >
using   namespace  std;
const   int  N = 2001 ;
int  dp[N][N]; // dp[i][j]表示i张卡片分成j堆的情况数
int  main()
{
    
int t,i,j;
    
int num[N];

    
for(i=1;i<=N-1;i++)
        dp[i][i] 
= dp[i][1= 1;

    
for(j=2;j<N-1;j++)//堆数
        for(i=j+1;i<=N-1;i++)//卡片数
            dp[i][j] =( (dp[i-1][j] * j)%10000 + dp[i-1][j-1] ) % 10000;

    
for(i=1;i<=N-1;i++)
    
{
        num[i] 
= 0;
        
for(j=1;j<=i;j++)
        
{
            num[i] 
+= dp[i][j];
            num[i] 
%= 10000;
        }

        num[i] 
%= 1000;
    }

    scanf(
"%d",&t);
    
while(t--)
    
{
        scanf(
"%d",&i);
        printf(
"%d\n",num[i]);
    }

    
return 0;
}