"HNOI2013 Competition"

CQOI2009 round robin

Description

\ (n \) team competition, two teams race each time, flat \ (1 \) wins \ (3 \) negative \ (0 \) .

Given the team's final score, the number of possible points table requirements.

\ (1 \ leq n \ leq 8 \) .

Solution

Once every two race teams, apparently had conducted \ (\ frac {n \ times (n-1)} {2} \) games.

Talk about violence found:

  1. We enumerate all the games, and who is playing, how about the situation.
  2. We enumerate match each person's situation, everyone to compete with people behind him (assuming \ (3 \) person, then enumerate \ (1 \ 2 \ 1 \ 3 \ 2 \ 3 \) ) . There is a qualitative change of the algorithm, the following algorithms are improved based on the algorithm.

Let's start pruning:

  1. Pruning math: Let wins total for the \ (the X-\) , to draw a total of \ (the y-\) , a total score for the \ (SUM \) . There \ (X \ Y + Times. 3 \ 2 = SUM Times \) , \ (X + Y = \ {n-FRAC \ Times (n-+. 1)} {2} \) . Below we got settled explain them elementary equation:

    \[2 \times(x+ y) = n \times (n + 1)\]

    \[n \times(n + 1) + x = sum\]

    \[x = sum - n \times (n + 1)\]

    \[y = \frac{\frac{n \times( n + 1)}{2} - 3 \times x} {2}\]

    Obviously, we can not wins and a draw more than calculation.

  2. Feasibility pruning: if the current people are playing to win no matter how the score is less than the required returns. Suppose the current first \ (i \) individual competition, then a maximum win \ ((n - i + 1 ) \) field.

  3. Optimality pruning: if a man and his people behind the game is over, his score and the title given scores of different returns. If a game so that the current score is greater than a given score, then returns during the race.

  4. Search Order pruning: We descending order of data input. Sensibility to understand it, we first calculate large, large multi-state, multi-state early on by our various pruning shears gone (without time out).

Kaka often before. The code a little, see the following data enhanced version.

HNOI2013 game

Description

\ (n \) team competition, two teams race each time, flat \ (1 \) wins \ (3 \) negative \ (0 \) .

Given the team's final score, the number of possible points table requirements.

\ (. 1 \ n-Leq \ Leq 10 \) . (Note that data range)

Solution

This question is the result of enhanced data, the original practice time out. Here to tell a magical optimization: memories of the search.

\(a \ b \ c \ d \ e \ f \ g\)

Assuming that first searched \ (d \) , we determined the \ (abcd \) of a state. The total number is now as \ (efg \) the number of programs. Obviously, \ (ABCD \) number of the program is to determine the front, then in accordance with the previous method, the number of programs back we need a recursive calculations, this is no problem, but we found that, \ (ABCD \) status may be more than a seed, we came back in the back update \ (abcd \) , we found that we were once again on the \ (defg \) search, we found \ (abcde \) is a state need \ (fg \) the number of programs.

So how state memory design? Since \ (abcd \) different states, it could lead to \ (efg \) different program number. With junior high school learned hash resolve to discrete, here unordered_map. First before ordering the hash.

Code

#include <bits/stdc++.h>
using namespace std;
#define re register
#define F first
#define S second
typedef long long ll;
typedef pair<int, int> P;
const int N = 10 + 5, INF = 0x3f3f3f3f, Base = 28, p = 1e9 + 7;
inline int read() {
    int X = 0,w = 0; char ch = 0;
    while(!isdigit(ch)) {w |= ch == '-';ch = getchar();}
    while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48),ch = getchar();
    return w ? -X : X;
}
int n, m, sum, win, draw;
int a[N], b[N], score[N];
unordered_map <ll, int> mp;
bool cmp(int a, int b){
    return a > b;
}
inline ll dfs(int x, int y){
    if (score[x] + (n - y + 1) * 3 < a[x]) return 0;
    if (x == n) return 1;
    if (y == n + 1){
        if (score[x] != a[x]) return 0;
        for (int i = x + 1; i <= n; i++) b[i] = a[i] - score[i];
        sort(b + x + 1, b + n + 1);
        ll key = 0;
        for (int i = x + 1; i <= n; i++) key = key * Base + b[i];
        if (mp.find(key) != mp.end()) return mp[key];
        else return mp[key] = dfs(x + 1, x + 2);
    } 
    ll ans = 0;
    if (win && score[x] + 3 <= a[x]){
        score[x] += 3; win--;
        ans += dfs(x, y + 1);
        score[x] -= 3; win++;
    }
    if (draw && score[x] + 1 <= a[x] && score[y] + 1 <= a[y]){
        score[x]++, score[y]++; draw--;
        ans += dfs(x, y + 1);
        score[x]--, score[y]--; draw++;
    } 
    if (win && score[y] + 3 <= a[y]){
        score[y] += 3; win--;
        ans += dfs(x, y + 1);
        score[y] -= 3; win++;
    } 
    return ans % p;
}
int main(){
    n = read(); 
    for (int i = 1; i <= n; i++) a[i] = read(), sum += a[i];
    sort(a + 1, a + n + 1, cmp);
    win = sum - n * n + n;
    draw = (sum - 3 * win) / 2;
    printf("%lld\n", dfs(1, 2) % p);
    return 0;
}

Guess you like

Origin www.cnblogs.com/lyfoi/p/11443670.html