专栏文章
P14364
P14364题解参与者 7已保存评论 6
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 6 条
- 当前快照
- 1 份
- 快照标识符
- @minfgziz
- 此快照首次捕获于
- 2025/12/02 01:33 3 个月前
- 此快照最后确认于
- 2025/12/02 01:33 3 个月前
贡献延后计算。什么意思?分析一下这个过程,设未被招聘上的人数为 ,若当前 大家都一样,否则 则 都一样;而且 是不降的。如此,我们在 dp 的时候将所有数划分为 和 的两集合 ,当 增加时考察哪些数从 ,在这时计算这些数带来的贡献。具体的:
记 表示考虑了 ,有 个没招聘上,其中有 个的 。在 的时候考察 当中有多少个是 的。具体的,以下给出转移:(记 )
- 若 :则此时无论如何都未招聘上, 必然加一,则考察 和 的大小:
- 若 :枚举 的个数 ,
- 若 :枚举 的个数 ,
- 若 :
- 若 :则未被招聘上, 加一,枚举 的个数 ,
- 若 :则被招聘上,
由于 而 ,故上述做法暴力 dp 即为 。
CPP#include<bits/stdc++.h>
// #define int long long
// #pragma GCC optimize(3,"Ofast","inline")
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ll long long
#define bint __int128
#define ull unsigned long long
#define uint unsigned int
#define ld double
#define PII pair<int,int>
#define chkmax(a,b) a=max(a,b)
#define chkmin(a,b) a=min(a,b)
#define umap unordered_map
#define rep(k,l,r) for(int k=l;k<=r;++k)
#define per(k,r,l) for(int k=r;k>=l;--k)
#define cl(f,x) memset(f,x,sizeof(f))
#define pcnt(x) __builtin_popcount(x)
#define lg(x) (31-__builtin_clz(x))
using namespace std;
void file_IO() {
freopen("employ.in","r",stdin);
freopen("employ.out","w",stdout);
}
bool M1;
const int INF=0x3f3f3f3f;
const ll INFLL=0x3f3f3f3f3f3f3f3f;
const ld eps=1e-9;
struct mint {
...
};
const int N=5e2+5;
mint jc[N],inv_jc[N];
void init(int n=5e2) {
jc[0]=1;
rep(i,1,n)
jc[i]=jc[i-1]*i;
inv_jc[n]=~jc[n];
per(i,n-1,0)
inv_jc[i]=inv_jc[i+1]*(i+1);
}
mint C(int n,int m) {
if(m<0||n<m)
return 0;
return jc[n]*inv_jc[n-m]*inv_jc[m];
}
mint P(int n,int m) {
if(m<0||n<m)
return 0;
return jc[n]*inv_jc[n-m];
}
int c[N],pre[N];
mint f[N][N][N];
char s[N];
void solve() {
int n,m;
scanf("%d%d",&n,&m);
scanf("%s",s+1);
rep(i,1,n) {
int x;
scanf("%d",&x);
++c[x];
}
pre[0]=c[0];
rep(i,1,n)
pre[i]=pre[i-1]+c[i];
f[0][0][0]=1;
rep(i,1,n) {
rep(j,0,i-1) {
rep(k,0,i-1) {
if(s[i]==48) {
rep(t,0,min(k,c[j+1])) {
if(pre[j+1]>=(i-1)-(k-t))
f[i][j+1][k-t]+=f[i-1][j][k]*C(c[j+1],t)*P(k,t)*(pre[j+1]-((i-1)-(k-t)));
f[i][j+1][k-t+1]+=f[i-1][j][k]*C(c[j+1],t)*P(k,t);
}
} else {
rep(t,0,min(k,c[j+1])) {
if(pre[j+1]>=(i-1)-k)
f[i][j+1][k-t]+=f[i-1][j][k]*C(c[j+1],t)*P(k,t)*(pre[j]-((i-1)-k));
}
f[i][j][k+1]+=f[i-1][j][k];
}
}
}
}
mint res=0;
rep(j,0,n-m)
res+=f[n][j][n-pre[j]]*jc[n-pre[j]];
printf("%d\n",res.x);
}
bool M2;
// g++ employ.cpp -std=c++14 -Wall -O2 -o employ
signed main() {
file_IO();
int testcase=1;
init();
// scanf("%d",&testcase);
while(testcase--)
solve();
debug("used time = %dms\n",(signed)(1000*clock()/CLOCKS_PER_SEC));
debug("used memory = %dMB\n",(signed)((&M1-&M2)/1024/1024));
return 0;
}
相关推荐
评论
共 6 条评论,欢迎与作者交流。
正在加载评论...