【LG3230】[HNOI2013]比赛

题面

洛谷

题解

img

代码

(50pts)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

inline int gi() {
    register int data = 0, w = 1;
    register char ch = 0;
    while (ch != '-' && (ch > '9' || ch < '0')) ch = getchar();
    if (ch == '-') w = -1 , ch = getchar();
    while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    return w * data;
}
int N, go[20];
int a[20][20];
int s[20]; //当前x队获得了多少分
int ans = 0;
int tot = 0; 
int score = 0; 
void dfs(int x, int y) { //刷到了表的第x行,第y列
    if (score > tot) return ; 
    if (x == N + 1) { 
        bool F = 1; 
        for (int i = 1; i <= N; i++)
            if (s[i] != go[i]) {
                F = 0; break; 
            }
        ans += F; 
        if (ans == 1000000007) ans = 0; 
    } else {
        //这一盘输了
        score += 3; 
        s[y] += 3; 
        if (s[y] > go[y]) goto nxt1; 
        if (s[x] > go[x]) {	
        	score -= 3; 
    		s[y] -= 3;
            return ; 
        }
        if (s[x] + 3 * (N - y) < go[x]) goto nxt1; 
        if (s[y] + 3 * (N - x) < go[y]) {
    		score -= 3; 
        	s[y] -= 3;
            return ; 
        } 
        if (y == x - 1) dfs(x + 1, 1); 
        else dfs(x, y + 1);
        nxt1 : { }
        score -= 3; 
        s[y] -= 3;
        //这一盘赢了
        score += 3; 
        s[x] += 3;
        if (s[x] > go[x]) goto nxt2; 
        if (s[y] > go[y]) {
            s[x] -= 3; 
            score -= 3;
            return ; 
        }
        if (s[y] + 3 * (N - x) < go[y]) goto nxt2;
        if (s[x] + 3 * (N - y) < go[x]) {
            s[x] -= 3; 
            score -= 3;
            return ; 
        }
        if (y == x - 1) dfs(x + 1, 1); 
        else dfs(x, y + 1); 
        nxt2 : { }
        s[x] -= 3; 
        score -= 3; 
        //这一盘和了
        score += 2; 
        s[x]++, s[y]++; 
        if (s[x] > go[x] || s[y] > go[y]) {
            score -= 2; 
            s[x]--, s[y]--; 
            return ;
        }
        if (s[y] + 3 * (N - x) < go[y]) {
            s[x]--, s[y]--; 
        	score -= 2; 
            return ;
        }
        if (s[x] + 3 * (N - y) < go[x]) {
            s[x]--, s[y]--; 
        	score -= 2; 
            return ;
        }
        if (y == x - 1) dfs(x + 1, 1); 
        else dfs(x, y + 1);
        s[x]--, s[y]--; 
        score -= 2; 
    } 
} 
int main () {
    N = gi();
    for (int i = 1; i <= N; i++) tot += go[i] = gi(); 
    dfs(2, 1);
    printf("%d
", ans); 
    return 0; 
} 

(100pts)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> 
#include<cmath> 
#include<algorithm>
#include<map> 
using namespace std;
typedef unsigned long long ull; 
#define Mod 1000000007
inline void add(int &x, int y) { x += y; if (x >= Mod) x -= Mod; } 
int N, a[20], tmp[20]; 
map<ull, int> mp; 
int dfs(int x, int y) { 
    if (a[x] > (x - y) * 3) return 0;
    int res = 0; ull hs = 0;
    if (x == y) { 
        if (x == 1) return 1;
        for (int i = 1; i < x; i++) tmp[i] = a[i];
        hs = x - 1; sort(&tmp[1], &tmp[x]);
        for (int i = 1; i < x; i++) hs = 27 * hs + tmp[i];
        return mp.find(hs) != mp.end() ? mp[hs] : mp[hs] = dfs(x - 1, 1); 
    }
    if (a[x] >= 3) a[x] -= 3, add(res, dfs(x, y + 1)), a[x] += 3;
    if (a[x] && a[y]) --a[x], --a[y], add(res, dfs(x, y + 1)), ++a[x], ++a[y];
    if (a[y] >= 3) a[y] -= 3, add(res, dfs(x, y + 1)), a[y] += 3;
    return res; 
} 
int main () {
    cin >> N;
    for (int i = 1; i <= N; i++) cin >> a[i];
    sort(&a[1], &a[N + 1], greater<int>()); 
    printf("%d
", dfs(N, 1)); 
    return 0; 
} 
原文地址:https://www.cnblogs.com/heyujun/p/10404938.html