HDU 4689 Derangement

DP.....

  f[i][j]表示前 i 个数还有 j 个+号没有放数字,-号全部放满。

  当 i 为+号时:1、当前这个数不放,即放在后面的位置中,f[i][j]+=f[i-1][j-1]。2、当前这个数放在前面的位置中,

f[i][j]+=f[i-1][j]*j。所以f[i][j]=f[i-1][j-1]+f[i-1][j]*j。

  当 i 为-号时:1、当前这个数放在后面的位置中,由前面+号未填的数来填-号,f[i][j]+=f[i-1][j]*j。2、当前这个数

放在前面的位置中,前面 j 个空位对应的数放在当前的-号位,当前这个数放在前面未放的+号位,

f[i][j]+=f[i-1][j+1]*j*j。


Derangement

Time Limit: 7000/7000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
Total Submission(s): 838    Accepted Submission(s): 251


Problem Description
A derangement is a permutation such that none of the elements appear in their original position. For example, [5, 4, 1, 2, 3] is a derangement of [1, 2, 3, 4, 5]. Subtracting the original permutation from the derangement, we get the derangement difference [4, 2, -2, -2, -2], where none of its elements is zero. Taking the signs of these differences, we get the derangement sign [+, +, -, -, -]. Now given a derangement sign, how many derangements are there satisfying the given derangement sign?
 

Input
There are multiple test cases. Process to the End of File.
Each test case is a line of derangements sign whose length is between 1 and 20, inclusively.
 

Output
For each test case, output the number of derangements.
 

Sample Input
   
   
   
   
+- ++---
 

Sample Output
   
   
   
   
1 13
 

Author
Zejun Wu (watashi)
 

Source
2013 Multi-University Training Contest 9
 


ll dp[N][N];
char s[N];
int main()
{
    while(scanf("%s",s)==1)
    {
        int n=strlen(s);
        memset(dp,0,sizeof dp);
        dp[0][0]=1;
        for(int k=0;k<=n;k++)
        {
            for(int i=0;i<=n;i++)
            {
                ll tmp = dp[k][i];
                if(tmp==0) continue;
              ///  printf("dp[%d][%d] = %d\n", k, i, dp[k][i]);
                if(s[k]=='+')
                {
                    dp[k+1][i+1] += tmp;
                    dp[k+1][i] += i * tmp;
                }
                if(s[k]=='-')
                {
                    dp[k+1][i] += 1ll * i * tmp;
                    if(i) dp[k+1][i-1] += 1ll * i * i * tmp;
                }
            }
           // putchar(10);
        }
        printf("%I64d\n", dp[n][0]);
    }
}

你可能感兴趣的:(HDU 4689 Derangement)