题目传送门
下面将给出一系列提示,请尝试根据提示独立解决此问题。当然你也可以跳过。
提示1:
枚举选进队的最后一名的成绩
提示2:
什么时候一个兔子一定达到了“qualified”个,什么时候不可能进队?
提示3:
是否可以一只兔子一只兔子的检验是否一定达到前qualified 个的分数,或可能入队,一定不入队。。。
提示4:
是否可以把当前入队的兔子个数,达到前qualified 个的最少人数作为dp状态?
题解
首先常规套路,对于分数分组的题目可以让达线的人分数尽可能的高,其他的尽可能的低。设
枚举最后一个入队的兔子的编号,然后考虑能有多少种可能。那么什么样的情况是不可能的呢?
- 假设队中的最后一名为 ,其中 在队中,如果 则一定不可能,这样就违背了最后一名的定义
- 如果x为队中的最后一名,那么达线人数大于qualified 。
这两个条件只需要一个好的状态就可以解决
考虑前i只兔子,第j只为选中的队中最后一名,至少k名达线的方案数。
code:
/* {AuThOr Gwj */
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin>>a
#define R2(a,b) cin>>a>>b
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*} */
const int MAXN=55;
int mi[MAXN],ma[MAXN];
LL dp[MAXN][MAXN][MAXN];//考虑前i个,选入队的人,达到分数线的人数
class RabbitProgramming{public:long long getTeams(vector<int> points,vector<string> standings,int q,int s){/*SOLUTION :枚举选中队伍的最后一名是多少 */int n=standings.size();rep(i,points.size()){if(points[i]<0){rep(j,n)if(standings[j][i]=='Y'){ma[j+1]-=points[i];}}else{rep(j,n)if(standings[j][i]=='Y')ma[j+1]+=points[i],mi[j+1]+=points[i];} }
// rb(i,1,n)
// cout<<ma[i]<<" "<<mi[i]<<endl; LL rest=0;rb(x,1,n){memset(dp,0,sizeof(dp));dp[0][0][0]=1; rb(i,1,n){rb(j,0,s)rb(k,0,q){if(i==x){if(j&&k)dp[i][j][k]=dp[i-1][j-1][k-1];} else{if(i<x){if(mi[i]>=ma[x]){if(k){dp[i][j][k]=dp[i-1][j][k-1];if(j)dp[i][j][k]+=dp[i-1][j-1][k-1];}}else{if(ma[i]>=ma[x]){if(j&&k){dp[i][j][k]=dp[i-1][j-1][k-1];}} dp[i][j][k]+=dp[i-1][j][k];}}else{if(mi[i]>ma[x]){if(k){dp[i][j][k]=dp[i-1][j][k-1];if(j)dp[i][j][k]+=dp[i-1][j-1][k-1];}}else{if(ma[i]>ma[x]){if(j&&k){dp[i][j][k]=dp[i-1][j-1][k-1];}} dp[i][j][k]+=dp[i-1][j][k];}}}}}rb(i,s,q){
// cout<<x<<"-"<<s<<"-"<<i<<"-"<<dp[n][s][i]<<endl;rest+=dp[n][s][i];}}return rest;}
};
同一类问题:
传送门