首页 > 代码库 > poj3934Queue(dp)

poj3934Queue(dp)

题目链接:

啊哈哈,点我点我

题意:

有n个幼儿园的孩纸,然后从中找出m对孩子能够让他们看到双方,这样以便他们交流。。

思路:

首先可以考虑把n-1个人已经排成了m-2对,那么只需要把这个最矮的随便插在队伍就可以凑成m对了。另外一种情况是先排成m-1对,然后把最矮的那一个放在对首或者队尾,这样就到了状态转移方程。

if(j>=2)

dp[i][j]=dp[i-1][j-2]*(i-2)

if(j>=1)

dp[i][j]=dp[i][j]+dp[i-1][j-1]*2;

然后最开始把1个人2个人的所有状态枚举出来。。然后对题目中给的范围进行预处理得到所有解,然后直接询问即可。问题就得到了完美的解决。

题目:

Queue
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 406 Accepted: 179

Description

Linda is a teacher in ACM kindergarten. She is in charge of n kids. Because the dinning hall is a little bit far away from the classroom, those n kids have to walk in line to the dinning hall every day. When they are walking in line, if and only if two kids can see each other, they will talk to each other. Two kids can see each other if and only if all kids between them are shorter then both of them, or there are no kids between them. Kids do not only look forward, they may look back and talk to kids behind them. Linda don’t want them to talk too much (for it’s not safe), but she also don’t want them to be too quiet(for it’s boring), so Linda decides that she must form a line in which there are exactly m pairs of kids who can see each other. Linda wants to know, in how many different ways can she form such a line. Can you help her? 

Note: All kids are different in height.

Input

Input consists of multiple test cases. Each test case is one line containing two integers. The first integer is n, and the second one is m. (0 < n <= 80, 0 <= m <= 10000). 
Input ends by a line containing two zeros.

Output

For each test case, output one line containing the reminder of the number of ways divided by 9937. 

Sample Input

1 0
2 0
3 2
0 0

Sample Output

1
0
4

Source


代码为:

#include<cstdio>
#include<cstring>
#include<iostream>
#define mod 9937
using namespace std;

int dp[80+10][10000+10];

void init()
{
    memset(dp,0,sizeof(dp));
    dp[1][0]=1;
    dp[2][1]=2;
    for(int i=3;i<=81;i++)
        for(int j=1;j<=10001;j++)
    {
        if(j>=2)  dp[i][j]=(dp[i-1][j-2]*(i-2))%mod;
        if(j>=1)  dp[i][j]=(dp[i][j]+dp[i-1][j-1]*2)%mod;
    }
}

int main()
{
    int n,m;
    init();
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)  return 0;
        cout<<dp[n][m]<<endl;
    }
    return 0;
}