P7519 [省选联考 2021 A/B 卷] 滚榜
考虑按照顺序分配 \(b\),如果分配的 \(b\) 之和不足 \(m\) ,可以把剩下的题目全部给最后一个人,所以对于一个排列,只用考虑祂 \(b\) 之和最小的分配方案。
先考虑一个暴力,设 \(f_{s,i,j,k}\) 表示已分配 \(b\) 的集合为 \(s\) 上一个分配的人为 \(j\),封榜后总共通过了 \(k\) 题的方案数。
考虑优化,由于 \(b\) 是不降的,所以当给 \(b_i\) 加上 \(x\) 时,后面的所有 \(b\) 都的加上 \(x\),相对大小不变,所以可以贡献提前算。最后注意一下第一个 \(b\) 必须比最大的那个数大和相同题目时按编号排序。
代码
/*
Luogu P7519 [省选联考 2021 A/B 卷] 滚榜
2026-03-05
*/
#include<bits/stdc++.h>
using namespace std;
namespace IO{
template<typename T>
inline void read(T&x){
x=0;char c=getchar();bool f=0;
while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
f?x=-x:0;
}
template<typename T>
inline void write(T x){
if(x==0){putchar('0');return ;}
x<0?x=-x,putchar('-'):0;short st[50],top=0;
while(x) st[++top]=x%10,x/=10;
while(top) putchar(st[top--]+'0');
}
inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
inline void write(char c){putchar(c);}
inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
#define ll long long
const int maxn=20,maxm=510;
int n,m,a[maxn],f[(1<<13)][maxn][maxm],id;
signed main(){
read(n,m);
for(int i=1;i<=n;i++) read(a[i]),id=a[i]>a[id]?i:id;
f[0][0][0]=1;
for(int i=0;i<(1<<n);i++) for(int j=0;j<=n;j++){
if(j&&!(i&(1<<j-1))) continue;
int g=0;
for(int k=1;k<=n;k++) g+=!!(i&(1<<k-1));
g=n-g;
for(int nt=1;nt<=n;nt++){
if(i&(1<<nt-1)) continue;
int gx;
if(a[nt]>a[j]) gx=0;
else if(a[nt]<=a[j]) gx=a[j]-a[nt]+(nt>j);
if(j==0) gx=a[id]-a[nt]+(nt>id);
for(int k=0;k<=m;k++){
if(k+g*gx>m) break;
f[i^(1<<nt-1)][nt][k+g*gx]+=f[i][j][k];
}
}
}
ll ans=0;
for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) ans+=f[(1<<n)-1][i][j];
write(ans);
return 0;
}

浙公网安备 33010602011771号