• Topcoder 10880


    vjudge链接

    为叙述简便,把题中的 (qualified) 称为 (k)(selected) 称为 (sel)

    考虑一组(大小为 (sel) 的)兔子能被选中的条件。可以发现,当且仅当它们能同时排进前 (k) 时,它们有机会被选中。很明显,我们要让这 (k) 只兔子分数尽可能大,其它兔子分数尽可能小。

    这个条件是否能满足,取决于这 (sel) 只兔子中最不给力的那只。所以,考虑枚举这只兔子,假设为 (low)

    那么 (low) 放在未选的兔子中的排名必然不大于 (k - sel + 1)

    可以设计出(dp)状态:(dp_{i,s,rnk}) 表示考虑到第 (i) 只非 (low) 的兔子,选了 (s) 只兔子进队,当前 (low) 在未选的兔子中排名 (rnk) 的方案数。

    转移有三种:

    这只兔子最好情况下排在 (low) 前面,且进队了,转移到 (dp_{i+1,s+1,rnk})

    这只兔子最坏情况下排在 (low) 前面,而没进队,转移到 (dp_{i+1,s,rnk+1})

    这只兔子最坏情况下排在 (low) 后面,也没进队,转移到 (dp_{i+1,s,rnk})

    比较两只兔子谁在前,可以转化为二元组 ((score, -id)) 再比大小(毕竟第二关键字要从小到大)

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mit map<int,int>::iterator
    #define sit set<int>::iterator
    #define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
    #define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
    #define ltype int
    #define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
    #define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
    #define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mpr make_pair
    #define pb push_back
    #define fastio ios::sync_with_stdio(false)
    #define check(x) if(x>=mod) x-=mod
    const int inf=0x3f3f3f3f,mod=1000000007;
    const double pi=3.1415926535897932,eps=1e-6;
    void chmax(int &x,int y){if(x < y) x = y;}
    void chmin(int &x,int y){if(x > y) x = y;}
    int qpow(int x,int y){
        int ret = 1;
        while(y) {
            if(y & 1) ret = (ll)ret * x % mod;
            x = (ll)x * x % mod;
            y >>= 1;
        }
        return ret;
    }
    int m,n,a[55],mx[55],mn[55],k,sel;
    char st[55][55];
    map<int,int> mp;
    ll dp[55][55][55],ans;
    ll mian()
    {
        //scanf("%d%d",&m,&n);
        //rep(i,1,m) scanf("%d",a+i);
        rep(i,1,n) {
            //scanf("%s",st[i]+1);
            rep(j,1,m) if(st[i][j] == 'Y') {
                if(a[j] < 0) mx[i] -= a[j];
                else mx[i] += a[j], mn[i] += a[j];
            }
            //printf("%d %d
    ",mx[i],mn[i]);
        }
        //scanf("%d%d",&k,&sel);
        rep(low,1,n) {
            pii res = mpr(mx[low], -low);
            dp[0][1][1] = 1;
            rep(ii,0,n-2) rep(sel,1,n) rep(rank,1,n){
                //int i = ii + (ii >= low);
                int i = ii + 1 + (ii + 1 >= low);
                pii x = mpr(mn[i], -i), y = mpr(mx[i], -i);
                if(y > res) {
                    dp[ii + 1][sel + 1][rank] += dp[ii][sel][rank];
                }
                if(x < res) {
                    dp[ii + 1][sel][rank] += dp[ii][sel][rank];
                }
                else {
                    dp[ii + 1][sel][rank + 1] += dp[ii][sel][rank];
                }
            }
            rep(i,1,k - sel + 1) ans += dp[n-1][sel][i];
            rep(ii,0,n-1) rep(sel,1,n) rep(rank,1,n) dp[ii][sel][rank] = 0;
        }
        return ans;
    }
    class RabbitProgramming
    {
        public:
        ll getTeams(vector<int> S,vector<string> ST,int K,int SEL) {
            m = S.size();
            n = ST.size();
            k = K;
            sel = SEL;
            rap(i,0,m) a[i + 1] = S[i];
            rap(i,0,n) rap(j,0,m) st[i + 1][j + 1] = ST[i][j];
            return mian();
        }
    }cwk;
    int main()
    {
        printf("%lld
    ",cwk.getTeams({1},{"Y","Y","N"},1,1));
    return 0;
    }
    
  • 相关阅读:
    CSV文件读取类
    一个参数处理类
    记一个mysql的问题
    php问题小记
    wsl开nginx和php-fpm遇到的几个小问题
    debian apache2.4 virtual host 使用
    debian 安装 apache2和php7
    杂记整理三:php、thinkphp和sql
    杂记整理二:linux与程序安装
    杂记整理一:javascript, jQuery 以及 ECMAscript
  • 原文地址:https://www.cnblogs.com/yz-beacon-cwk/p/14359007.html
Copyright © 2020-2023  润新知