题目链接;
URAL 1114 Boxes
题意:
有
n
个箱子,和
数据范围:
分析:
简单
dp
。
用
dp[i][j][k]
表示前
i
个箱子一共放置
状态转移方程:
初始化: dp[0][0][0]=1 。
答案就是:
Ans=∑j=0j≤A∑k=0k≤Bdp[n][j][k]
注意数据会超 long long 。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <climits>
#include <cmath>
#include <ctime>
#include <cassert>
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
using namespace std;
typedef long long ll;
const int MAX_N = 25;
const int MAX_M = 20;
const ll BASE = (ll)(1e9);
const int size = 10;
ll dp[MAX_N][MAX_M][MAX_M][size];
void solve(int n, int A, int B)
{
memset(dp, 0, sizeof(dp));
dp[0][0][0][0] = 1;
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= A; ++j) {
for(int k = 0; k <= B; ++k) {
for(int jj = 0; jj <= j; ++jj) {
for(int kk = 0; kk <= k; ++kk) {
for(int t = 0; t < size - 1; ++t) {
dp[i][j][k][t] += dp[i - 1][jj][kk][t];
dp[i][j][k][t + 1] += dp[i][j][k][t] / BASE;
dp[i][j][k][t] %= BASE;
//if(dp[i][j][k][t]) printf("dp[%d][%d][%d][%d] = %lld\n", i, j, k, t, dp[i][j][k][t]);
}
}
}
//printf("dp[%d][%d][%d] = %lld\n", i, j, k, dp[i][j][k]);
}
}
}
ll ans[size];
memset(ans, 0, sizeof(ans));
for(int i = 0; i <= A; ++i) {
for(int j = 0; j <= B; ++j) {
for(int t = 0; t < size - 1; ++t) {
ans[t] += dp[n][i][j][t];
ans[t + 1] += ans[t] / BASE;
ans[t] %= BASE;
}
}
}
int st = 0;
for(int i = size - 1; i >= 0; --i) {
if(ans[i] > 0) {
printf("%lld", ans[i]);
st = i;
break;
}
}
for(int i = st - 1; i >= 0; --i) {
printf("%09lld", ans[i]);
}
printf("\n");
}
int main()
{
int n, A, B;
while(~scanf("%d%d%d", &n, &A, &B)) {
solve(n, A, B);
}
return 0;
}