hdu 1521 记忆化搜索

应该说,就是道DP题,最近用记忆化搜索用得老爽了,就用了~

/*
* hdu1521/win.cpp
* Created on: 2011-10-3
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

const int MAXN = 12;
const int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 };
int num[MAXN], sum[MAXN];
int dp[MAXN][MAXN];

int search(int n, int m) {
if (dp[n][m] >= 0) {
return dp[n][m];
}
if (sum[n] < m) {
dp[n][m] = 0;
return 0;
}
long long ret = 0;
for (int i = 0; i <= m && i <= num[n]; i++) {
ret += (long long) search(n - 1, m - i) * fac[m] / fac[m - i] / fac[i];
}
dp[n][m] = ret;
return ret;
}

void init(int n) {
for (int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
}
memset(dp, -1, sizeof(dp));
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}
sum[0] = 0;
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + num[i];
}
}

int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int n, m;
while (scanf("%d%d", &n, &m) == 2) {
init(n);
printf("%d\n", search(n, m));
}
return 0;
}
posted @ 2011-10-03 16:11  moonbay  阅读(169)  评论(0编辑  收藏  举报