您的位置:首页 > 其它

[HZNUOJ1524]排队买票(DP)

2016-03-18 19:31 260 查看
题目链接:http://acm.hznu.edu.cn/JudgeOnline/problem.php?id=1524

简单分析后可以知道每一个手持两元的小朋友前面,售票员手里至少有一个一元。

假设dp(i, j)表示当有i个1元和j个2元的时候的排队方法(不重复),那么有:

dp(i, j)=∑k[0, j]dp(i-1, k), (i >= j)

题干讲n个人和k个人内部不同位置也算新的排列方法。那么最后要乘上A(k,k)*A(n,n)

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>

using namespace std;

const int maxn = 15;
int n, m, k;
int dp[maxn][maxn];

int main() {
// freopen("in", "r", stdin);
scanf("%d %d %d", &m, &n, &k);
memset(dp, 0, sizeof(dp));
int ak = 1, an = 1;
for(int i = 1; i <= k; i++) ak *= i;
for(int i = 1; i <= n; i++) an *= i;
dp[1][0] = 1;
dp[1][1] = 1;
for(int i = 2; i <= n; i++) {
for(int j = 0; j <= i; j++) {
for(int k = 0; k <= j; k++) {
dp[i][j] += dp[i-1][k];
}
}
}
printf("%d\n", dp
[k]*ak*an);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: