【DP】 TOJ 4103. Chinese Hockey 3

注意到只要是递减数列,总和为总分数,都符合题目意义。。。dp暴力打表,交表即可。。。

#include <bits/stdc++.h>
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 100005
#define maxm 100005
#define eps 1e-7
#define mod 1000000007
#define INF 0x3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid 
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL; 
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head

LL dp[4000][200][55];
int n;

LL dfs(int sum, int pre, int pos)
{
	if(dp[sum][pre][pos] != -1) return dp[sum][pre][pos];
	if(pos == n + 1) {
		if(sum == 3 * n * (n - 1) / 2) return true;
		else return false;
	}
	int limit = 3 * pos * (n - pos) + pos * (pos - 1) * 3 / 2 - sum;
	LL ans = 0;
	for(int i = 0; i <= pre && i <= limit; i++) {
		ans = (ans + dfs(sum + i, i, pos + 1)) % mod;
	}
	return dp[sum][pre][pos] = ans % mod;
}

int work()
{
	memset(dp, -1, sizeof dp);
	return dfs(0, (n - 1) * 3, 1);
}	

int main()
{
//	freopen("output", "w", stdout);
	for(int i = 1; i <= 50; i++) {
		n = i;
		printf("if(n == %d) ", i);
		printf("printf(\"%lld\");", work());
		printf("\n");
	}

	return 0;
}

#include <stdio.h>

using namespace std;

void work()
{
	int n;
	scanf("%d", &n);
	if(n == 1) printf("1");
if(n == 2) printf("2");
if(n == 3) printf("8");
if(n == 4) printf("37");
if(n == 5) printf("198");
if(n == 6) printf("1178");
if(n == 7) printf("7548");
if(n == 8) printf("50944");
if(n == 9) printf("357855");
if(n == 10) printf("2595250");
if(n == 11) printf("19313372");
if(n == 12) printf("146815503");
if(n == 13) printf("136158488");
if(n == 14) printf("927025933");
if(n == 15) printf("65653738");
if(n == 16) printf("215408350");
if(n == 17) printf("746589264");
if(n == 18) printf("724066327");
if(n == 19) printf("631274816");
if(n == 20) printf("422001336");
if(n == 21) printf("7146650");
if(n == 22) printf("407217283");
if(n == 23) printf("393518927");
if(n == 24) printf("965151303");
if(n == 25) printf("895251280");
if(n == 26) printf("864749285");
if(n == 27) printf("934373752");
if(n == 28) printf("467108499");
if(n == 29) printf("418735743");
if(n == 30) printf("451847922");
if(n == 31) printf("890597718");
if(n == 32) printf("824730990");
if(n == 33) printf("739940095");
if(n == 34) printf("858720713");
if(n == 35) printf("600431442");
if(n == 36) printf("577631035");
if(n == 37) printf("867745635");
if(n == 38) printf("3561686");
if(n == 39) printf("302514002");
if(n == 40) printf("527947240");
if(n == 41) printf("805543258");
if(n == 42) printf("150530321");
if(n == 43) printf("534209877");
if(n == 44) printf("85487795");
if(n == 45) printf("939816214");
if(n == 46) printf("315353659");
if(n == 47) printf("496074452");
if(n == 48) printf("538654703");
if(n == 49) printf("326456510");
if(n == 50) printf("82203529");
printf("\n");

	
}

int main()
{
	int _;
	scanf("%d", &_);
	while(_--) work();
}


你可能感兴趣的:(dp)