• [HNOI2013]比赛 搜索


    [HNOI2013]比赛

    搜索。

    LG传送门

    直接暴力有60,考场上写的60,结果挂成40。

    考虑在暴力的同时加个记忆化,把剩下的球队数和每支球队的得分情况hash一下,每次搜到还剩(t)个队的时候就在哈希表里找一下,有就拿来算答案,没有就把这次的结果存进哈希表。复杂度(O()能过())

    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #define R register
    #define I inline
    #define L long long
    using namespace std;
    const int N = 13, B = 29, yyb = 1e9 + 7;
    int a[N], b[N], f[N], sta[N], stp, n, t, k;
    unordered_map <L, L> m;
    I int cmp(int x, int y) { return x > y; }
    L dfs(int x, int y) {
        if (x == n)
            return 1;
        if (f[x] + (n - y + 1) * 3 < a[x])
            return 0;
        L o = 0;
        if (y > n){
            R int i;
            for (i = x + 1; i <= n; ++i)
                b[i] = a[i] - f[i];
            sort(b + x + 1, b + n + 1);
            for (i = x + 1; i <= n; ++i)
                o = o * B + b[i];
            if (m.find(o) != m.end())
                return m[o];
            else
                return m[o] = dfs(x + 1, x + 2);
        }
        if (f[x] + 3 <= a[x] && k)
            f[x] += 3, --k, o += dfs(x, y + 1), f[x] -= 3, ++k;
        if (f[y] + 3 <= a[y] && k)
            f[y] += 3, --k, o += dfs(x, y + 1), f[y] -= 3, ++k;
        if (f[x] < a[x] && f[y] < a[y] && t)
            ++f[x], ++f[y], --t, o += dfs(x, y + 1), --f[x], --f[y], ++t;
        return o % yyb;
    }
    int main() {
        scanf("%d", &n), t = n * (n - 1) * 3 >> 1;
        for (R int i = 1; i <= n; ++i)
            scanf("%d", &a[i]), t -= a[i];
        sort(a + 1, a + n + 1, cmp), k = (n * (n - 1) >> 1) - t, printf("%I64d", dfs(1, 2));
        return 0;
    }
    
    
  • 相关阅读:
    Leet_Code_567_字符串排列
    LeetCode_424_替换后的最长字符串
    LeetCode_139_单词拆分
    为Linux 添加自定义命令
    javax.validation 自定义校验器
    MYBatis 动态SQL
    SPRING BOOT 15.1 TEST
    B-树和B+树的应用:数据搜索和数据库索引
    设计模式-代理
    数据结构与算法
  • 原文地址:https://www.cnblogs.com/cj-chd/p/10299328.html
Copyright © 2020-2023  润新知