Topcoder 10880 - RabbitProgramming 题解

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\n",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\n",cwk.getTeams({1},{"Y","Y","N"},1,1));
return 0;
}
posted @ 2021-02-01 21:57  beacon_cwk  阅读(176)  评论(0编辑  收藏  举报