[CQOI2009] round robin - memory search

\ (n \) teams competition, two teams race each time. If the two teams tie, then each scored \ (1 \) points; otherwise, the winning team get \ (3 \) points, defeated the team get \ (0 \) points. Given the team's final score, find how many possible score table.

Solution

Search + vigorously pruning

First enumeration 1v2,1v3, ..., 1vN, and then enumerate 2v3,2v4, ..., 2vN, and so on

In order to accelerate the owners in accordance with the score from small to large

Then use the hash memory of what

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 10;
const int mod = 11451419198107;
int a[N],n;
map<int,int> h;

int gethash(int i,int j) {
    int res = i*17+j;
    for(int i=1;i<=n;i++) ((res*=17)+=a[i])%=mod;
    return (res+mod)%mod;
}

int dfs(int i,int j) {
    if(a[i]<0) return 0;
    if(j>n) {
        if(a[i]) return 0;
        ++i, j=i+1;
    }
    if(h.find(gethash(i,j))!=h.end()) {
        return h[gethash(i,j)];
    }
    int tmp=0;
    if(i==n && a[i]==0) ++tmp;
    else {
        if(a[i]>0 && a[j]>0) {
            --a[i]; --a[j];
            tmp += dfs(i,j+1);
            ++a[i]; ++a[j];
        }
        if(a[i]>2) {
            a[i]-=3;
            tmp += dfs(i,j+1);
            a[i]+=3;
        }
        if(a[j]>2) {
            a[j]-=3;
            tmp += dfs(i,j+1);
            a[j]+=3;
        }
    }
    h[gethash(i,j)]=tmp;
    return tmp;
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    cout<<dfs(1,2)<<endl;
}

Guess you like

Origin www.cnblogs.com/mollnn/p/12640666.html