类型:DP
题目:http://acm.timus.ru/problem.aspx?space=1&num=1036
思路:状态f(i, j)表示前i个数字和为j的方案数容易得到f(i, j) =∑ f(i - 1, j - k) (0 <= k <= 9)
需要用高精度计算
!!!s为奇数的情况// ural 1036. Lucky Tickets
// wa wa ac 0.203s
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)
int n, s, ts;
short dp[60][1010][150];
short endd[300];
void add(int x, int y, int z) {
int s = 0, c = 0, i;
FOR(i, 0, 150) {
s = c + dp[x][y][i] + dp[x - 1][y - z][i];
dp[x][y][i] = s % 10;
c = s / 10;
}
}
void multi(int t, int j) {
int i, s = 0, c = 0;
FOR(i, 0, 300) {
if(i + j >= 300)
break;
s = endd[i + j] + dp[n][ts][i] * t + c;
endd[i + j] = s % 10;
c = s / 10;
}
}
void solve() {
int i, j, k;
cin>>n>>s;
if(s & 1) {
cout<<"0\n";
return ;
}
ts = s / 2;
dp[0][0][0] = 1;
FORE(i, 1, n)
FORE(k, 0, ts)
FORE(j, 0, min(k, 9))
add(i, k, j);
FOR(i, 0, 150)
multi(dp[n][ts][i], i);
FORDE(i, 299, 0)
if(endd[i] != 0)
break;
if(i == -1)
cout<<"0\n";
else {
FORDE(j, i, 0)
cout<<endd[j];
cout<<endl;
}
}
int main() {
solve();
return 0;
}