hdu2068-RPG的错排-(dp递推式)

去年看错排公式,死都看不懂,基础扎实之后再来看就略懂了。

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

解析公式:比如有n个元素,各对应n个正确位置,dp[n]表示这n个元素全部排错的可能。

比如有元素:1 2 3 4 5 ... k ... n

1.假设第n个元素,要它在错误的位置上,则有n-1种情况。

2.对于剩下的n-1个元素,随便取一个位置上的元素k,要它在错误的位置上,则有2种情况

1)它在第n个元素的位置,相当于n和k两个元素交换位置,和其它没有关系,剩余n-2个元素爱怎么排就怎么排,dp[n-2]

2)不在第n个元素的位置,假设把n作为k的正确位置,则1 2 3 4 5...(k)...n,除去正确位置k,就是n-1个元素放在n-1个位置上,dp[n-1]。

初始化:

dp[1]=0;

dp[2]=1;

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

hdu2068:http://acm.hdu.edu.cn/showproblem.php?pid=2068

题解:

有n个人要猜对一半以上,就是错一半以下,排错公式。

对于这些错的人,也可以互不相同,组合数公式。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

ll ans[20];
ll c[30][30];///C(n,m) = C(n-1,m) + C(n-1,m-1)

void init()
{
    memset(ans,0,sizeof(ans));
    memset(c,0,sizeof(c));
    ans[0]=1;///一个都没有错只有1种
    ans[1]=0;
    ans[2]=1;
    ans[3]=2;
    for(ll i=4;i<20;i++)
        ans[i] = (i-1) * ( ans[i-1]+ans[i-2] );

    for(int i=0;i<30;i++)
        c[i][0]=1;
    for(int i=1;i<30;i++)
        for(int j=1;j<=i;j++)
        c[i][j] = c[i-1][j] + c[i-1][j-1];

}

int main()///hdu2068 RPG错排
{
    init();
    int n;
    while(scanf("%d",&n) && n)
    {
        ll res=0;
        for(int i=0;i<=n/2;i++)
            res += ans[i] * c[n][i];
        printf("%lld\n",res);
    }
    return 0;
}

hdu2049:http://acm.hdu.edu.cn/showproblem.php?pid=2049

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

ll ans[30];
ll c[30][30];///C(n,m) = C(n-1,m) + C(n-1,m-1)

void init()
{
    memset(ans,0,sizeof(ans));
    memset(c,0,sizeof(c));
    ans[0]=0;///一个都没有错只有1种
    ans[1]=0;
    ans[2]=1;
    ans[3]=2;
    for(ll i=4;i<25;i++)
        ans[i] = (i-1) * ( ans[i-1]+ans[i-2] );

    for(int i=0;i<30;i++)
        c[i][0]=1;
    for(int i=1;i<30;i++)
        for(int j=1;j<=i;j++)
        c[i][j] = c[i-1][j] + c[i-1][j-1];

}

int main()///hdu2049 考新朗
{
    init();
    int n,t;
    scanf("%d",&t);

    while( t-- )
    {
        int n,m;
        scanf("%d%d",&n,&m);
        ll res=0;
        res = ans[m] * c[n][m];
        printf("%lld\n",res);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/shoulinniao/p/11173727.html

时间: 2024-10-26 13:02:31

hdu2068-RPG的错排-(dp递推式)的相关文章

hdu2068 RPG的错排 组合数/递推

1 #include<stdio.h> 2 long long arr[21]; 3 long long c(int a,int b) 4 { 5 long long i,sum=1,j; 6 for (i=a,j=1;i>=a-b+1,j<=b;i--,j++) sum=sum*i/j; 7 return sum; 8 } 9 void func() 10 { 11 int i; 12 arr[1]=0;arr[2]=1; 13 for(i=3;i<=26;i++) 14

HDU2068 RPG的错排 【组合+错排】

RPG的错排 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7874    Accepted Submission(s): 3217 Problem Description 今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁.RPG给他机会让他猜猜,第一次猜:R是

hdu2068 RPG的错排

RPG的错排 时间限制:1000/1000 MS(Java / Others)内存限制:32768/32768 K(Java / Others)总提交内容:16421接受的提交内容:6670 问题描述 今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁.RPG给他机会让他猜猜,第一次猜:R t是公主,P是草儿,G是月野兔;第二次猜:R t是草儿,P是月野兔,G是公主;第三次猜:R t是草儿,P是公主,G是月野兔; .....

ACM学习历程—HDU2068 RPG的错排(组合数学)

Description 今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁.RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔:第二次猜:R是草儿,P是月野兔,G是公主:第三次猜:R是草儿,P是公主,G是月野兔:......可怜的野骆驼第六次终于把RPG分清楚了.由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以

组合数学+递推式 hdu2068 RPG的错排

我的思路是这样的: 枚举正确的个数i,然后从n个位置中选择i个位置,C(n,i) 那么剩下的n-i个位置,都不是答案,我们暂时成为错位排列 现在的难点就在于,如何球错位排列 设F[i]表示i个数字,错位排列的种类数 那么,先只考虑前i-1个数字错位排列,暂时在第i个位置把数字i放上,此时是不合法的因为i第i个位置不能放i,所以要考虑把i和其他数字调换位置 在前i-1个位置中,选出一个位置,把这个位置的数字与数字i调换位置,可能的情况就有(i-1)*F[i-1] 看似情况全部考虑了,其实还有一种情

HDU 2068 RPG的错排

要求答对一半或以上就算过关,请问有多少组答案能使他顺利过关. 逆向思维,求答错一半或以下的组数 1,错排 错排公式的由来 pala提出的问题: 十本不同的书放在书架上.现重新摆放,使每本书都不在原来放的位置.有几种摆法? 这个问题推广一下,就是错排问题: n个有序的元素应有n!种不同的排列.如若一个排列式的所有的元素都不在原来的位置上,则称这个排列为错排.递推的方法推导错排公式 当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元

错排递推式推导

今天听课讲容斥,提到错排,突然发现错排公式什么的好像已经忘了233 努力地回忆了一下,算出前几项,终于还原出了那个递推式↓ f(n)=(n-1)*(f(n-1)+f(n-2)) 根据人赢的教导,只要思(yi)考(yin)下错排的构造就能记住了 然后就认(meng)认(you)真(yi)真(yang)地思(yi)考(yin)了下 用自己的理解把这玩意儿整理了一下↓ 先加一点平时我们说的错排通常是指1~n,f(i)≠i, 其实脑补一下,它也可以看成A,B两个集合,|A|=|B|,对于每一个Ai,都对

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

hdu2089(数位DP 递推形式)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 25802    Accepted Submission(s): 8967 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以