poj3934解题报告

来源:互联网 发布:什么是优化消费结构 编辑:程序博客网 时间:2024/06/05 01:19

题目大意:n个小朋友排队(每个小朋友都不一样高)。两个小朋友ab能够互相看见当且仅当排在它们中间的小朋友比ab都要矮。已知队伍中一共有m对小朋友可以互相看见,问有可能有多少种排队方式。

思路:应该拿DP来做,一开始我还想拿递归生成全排列,剪枝呢~~后来看了别人思路真的绝了

那个人的思路大概是这样:

状态变量d[i][j]表示i个人,j个对一共有多少种方式

然后对于每一种i个人组成j对的状态有两种决策:

1.(i-1)个人先组成(j-2)对,然后最矮的人插在彼此的间隙中,此时不会对原来的对数造成任何影响(因为这是最矮的)

if(j>=2)

d[i][j]=(d[i-1][j-2]*(i-2))%9937;   //中间有i-2个空可以让他插

2.(i-1)个人先组成(m-1)对,然后最矮的人照在两侧,此时也不会对原来的对数产生任何影响,而且只增加了一对。

(d[i][j]+d[i-1][j-1]*2) //  一首一尾两种情况

所以状态方程:

if(j>=2)

d[i][j]=(d[i-1][j-2]*(i-2))%9937;
if(j>=1)
d[i][j]=(d[i][j]+d[i-1][j-1]*2)%9937;

边界自己想吧 ~~


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
        int n,m,d[85][10100];
        memset(d,0,sizeof(d));
        d[1][0]=1;
        d[2][1]=2;
        for(int i=3;i<=80;i++)
                for(int j=0;j<=10000;j++)
                {
                        if(j>=2)
                        d[i][j]=(d[i-1][j-2]*(i-2))%9937;
                        if(j>=1)
                        d[i][j]=(d[i][j]+d[i-1][j-1]*2)%9937;
                }
                while(cin>>n>>m)
                {
                        if(n==0&&m==0) break;
                        cout<<d[n][m]<<endl;
                }
        return 0;
}


0 0
原创粉丝点击