动态规划-递推-HDU2048

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2048

全错=全不匹配

设当前全错的个数是dp[n]

那么前(n-1)个全错的话,第n个数就可以从前(n-1)个任意挑选一个进行交换,得到的即是全错的;

dp[n] += (n-1)*dp[n-1]

也可以从下面这种情况样获得全错的排列:

在前(n-1)个中挑出(n-2)个全错,仅有一个对的情况,第n个数只需要和这个对的交换就能得到全错的结果。

可供挑选的(n-2)个全错的情况,在(n-1)个数中,有(n-1)种;(n-2)个全错又有dp[n-2]种

所以:

dp[n] += (n-1)*dp[n-2]

最终递推式就是:

dp[i]=(i-1)*(dp[i-1]+dp[i-2]);

  
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define sc scanf 
#define pt printf
#define maxe 25600
#define maxv 55
#define maxn 21
#define mll unsigned long long
const int inf =2000000000;
mll dp[maxn];
mll w1[maxn],w2[maxn],b1[maxn],b2[maxn];
mll A[maxn];
int main()
{
    freopen("in.txt","r",stdin);
    mll i;
    A[1]=1; for(i=2;i<=20;++i) A[i]=A[i-1]*i;
    dp[2]=1,dp[3]=2; for(i=3;i<=20;++i) dp[i]=(i-1)*(dp[i-1]+dp[i-2]);
    int T,n;
    sc("%d",&T);
    while(T--)
    {
        sc("%d",&n);
        double ans = 1.0*dp[n]/A[n];
        ans*=100000.0;
        int res = (int)ans;
        if(res%10>=5) res=res-res%10+10;
        else res=res-res%10;
        res/=10;
        //pt("%d\n",res);
        i=4;
        char s[5];
        while(res!=0)
        {
            s[i]=res%10+'0'; res/=10; --i;
        }
        for(++i;i<=4;++i)
        {
            if(i==3) putchar('.');
            putchar(s[i]);
        }
        putchar('%'); putchar('\n');
    } 
    return 0;
}
HDU 2048

 

posted @ 2019-08-07 10:39  宁信  阅读(187)  评论(0编辑  收藏  举报