Codeforces Round 972 (Div. 2) 补题记录(A~C,E1)
dp round again
A
发现构造若干个 \(a\) 然后接若干个 \(e\) 接若干个 \(i\) 接若干个 \(o\) 再接若干个 \(u\) 且让这些字母的出现次数尽量相等最优。直接构造时间复杂度为 \(O(n)\)。
void solve(unsigned __testid=1){
int n;
cin>>n;
F(i,0,4){
int cnt=n/5;
if(n%5>i)++cnt;
F(j,1,cnt){
if(i==1)putchar('e');
if(i==2)putchar('i');
if(i==3)putchar('o');
if(i==4)putchar('u');
if(!i)putchar('a');
}
}
cout<<'\n';
}
B1
分类讨论 \(c\) 在 \(b_1\) 左、\(b_1\) 和 \(b_2\) 之间,\(b_2\) 右三种情况讨论。
void solve(unsigned __testid=1){
int n,m,q;cin>>n>>m>>q;
int b1,b2;cin>>b1>>b2;int c;cin>>c;
if(b1>b2)swap(b1,b2);
if(b1<=c&&c<=b2)cout<<(b2-b1)/2<<'\n';
else if(c<b1)cout<<b1-1<<'\n';
else cout<<n-b2<<'\n';
}
B2
在 B1 的基础上加一个二分求出 \(c\) 在 \(b\) 的哪一段区间即可。时间复杂度为 \(O(n+q\log n)\)。
int a[N],b[N];
void solve(unsigned __testid=1){
int n,m,q;cin>>n>>m>>q;
F(i,1,m)cin>>b[i];
sort(b+1,b+m+1);
F(i,1,q){
int x;cin>>x;
int l=1,r=m,best=-1;
if(x<b[1])cout<<b[1]-1<<'\n';
else if(x>b[m])cout<<n-b[m]<<'\n';
else{
while(l<=r){
int mid=l+r>>1;
if(b[mid]>=x)best=mid,r=mid-1;
else l=mid+1;
}
assert(~best);
// best-1 ~ best
cout<<(b[best]-b[best-1])/2<<'\n';
}
}
}
C
咚咚咚
一个十分复杂的做法。
设 \(f_{i,0/1/2/3/4}\) 表示第 \(i\) 个字符串以 \(n/a/r/e/k\) 开头最多可以获得多少得分。
首先可以发现字符串 \(s_i\) 中不是 \(n/a/r/e/k\) 的字符对答案毫无贡献,因此先删去。
然后进入 dp。首先设 \(f_{0,4}=0\) 为初始状态。
然后考虑做转移方程。
对于每一个字符串 \(s_i\) 和其开始字符 \(j\),都暴力扫描字符串 \(s_i\) 得到最后一个出现的位置 \(p\)。然后用 \(f_{i,p}\) 更新 \(f_{k,\text{Pre}(j)}\)(其中 \(\text{Pre}(j)\) 表示 \(j\) 循环的上一个字符是什么)。令 \(cnt\) 表示当前可以被匹配上的字符数,\(all\) 表示为 \(n/a/r/e/k\) 但是当前不能被匹配上的字符数。更新的时候:
- 考虑 \(\text{Pre}(j)=4\),此时可以直接从这个字符串打头,此时这个字符串对答案的贡献为 \(\lfloor\frac{cnt}{5}\rfloor\times 5-cnt\bmod 5-all\)。
- 枚举上一个被选择的字符串 \(s_k\),此时对答案的贡献为:
- 若 \(s_i\) 在 \(s_k\) 的基础上开辟了一个新的循环,那么:
- 若 \(\text{Pre}(j)=4\),则此时 \(s_k\) 最后一个循环已经被匹配,因此对答案的贡献为 \(0\)。
- 若 \(\text{Pre}(j)\neq 4\),则此时 \(s_k\) 最后一个循环没有被匹配,计算该循环剩下的未匹配字符数量 \(4-\text{Pre}(j)\),其就是对答案的贡献。
- 否则,因为还在上一个循环里所以对答案没有贡献。
- 计算 \(s_k\) 所属完整循环节数量 \(\lfloor\frac{cnt-4+\text{Pre}(j)}{5}\rfloor\times 5\) 也是对答案的贡献。
- 剩下的 \((cnt-4+\text{Pre}(j))\bmod 5\) 即为下一个循环但是没有被 \(narek\) 字符串所完全覆盖的长度,对答案的贡献为 \(-((cnt-4+\text{Pre}(j))\bmod 5)\)。
- 若 \(s_i\) 在 \(s_k\) 的基础上开辟了一个新的循环,那么:
最后的答案即为 \(\max f_{i,j}\)。
考虑依据上述转移方程暴力转移,时间复杂度为 \(O(n^2)\)。
void solve(unsigned __testid=1){
// freopen(".out","w",stdout);
int n,k;cin>>n>>k;
F(i,1,n)cin>>s[i];
F(i,1,n){
string t;
for(auto &j:s[i])
if(j=='n'||j=='a'||j=='r'||j=='e'||j=='k')
t+=j;
s[i]=t;
}
F(i,1,n){
len[i]=s[i].size();
s[i]=' '+s[i];
}
F(i,1,n)
F(j,0,4)
f[i][j]=-1e18;
int mx=0;
f[0][4]=0;
F(i,1,n){
char sp[]={'n','a','r','e','k'};
F(j,0,4){
int cnt=0,all=0;
int now=j;
F(k,1,len[i]){
if(s[i][k]==sp[now]){
now=(now+1)%5;
++cnt;
}else ++all;
}
if(!cnt)continue;
// cout<<"i=" <<i<<" then j can be "<<j<<", "<<cnt<<' '<<all<<'\n';
int pre=now-1;
if(pre<0)pre+=5;
now=pre;
pre=j-1;
if(pre<0)pre+=5;
if(pre==4)f[i][now]=max({cnt/5*5-all-cnt%5,f[i][now]});
F(k,1,i-1){
int cost=f[k][pre];
int cntt=cnt;
if(cnt<4-pre)cost-=cnt+all;
else{
if(pre!=4){
cnt-=(4-pre);
cost+=5-all;
cost+=pre+1;
}else cost-=all;
cost+=cnt/5*5;
cost-=cnt%5;
}
cnt=cntt;
// cout<<"WORI "<<k<<' '<<cnt<<' '<<cost<<' '<<now<<' '<<pre<<' '<<f[k][pre]<<" COMPARE "<<(cnt<4-pre)<<'\n';
f[i][now]=max(f[i][now],cost);
}
}
F(j,0,4)mx=max(mx,f[i][j]);
// cout<<"qwq "<<i<<' ';
// F(j,0,4)cout<<f[i][j]<<' ';
// cout<<'\n';
}
cout<<mx<<'\n';
}
D
咕咕咕。
E1
一个很 trival 的思路是设 \(f_{i,j,k}\) 表示当前匹配到 \(a\) 中第 \(i\) 个字符,选择到 \((j,k)\) 位置是否有必胜策略。
那么考虑枚举 \((p,q)\) 位置表示枚举第 \(i+1\) 个位置选择 \((p,q)\) 是否有必胜策略。那么 \(f_{i,j,k}\) 为 \(0\) 当且仅当所有合法的 \((p,q)\) 均满足 \(f_{i+1,p,q}=1\),否则 \(f_{i,j,k}\) 为 \(1\)。
时间复杂度为 \(O(n^5)\),但是发现每一次 \(O(n^2)\) 在连续矩阵中找答案所以考虑用 2D-前缀和优化,时间复杂度优化为 \(O(n^3)\) 可以通过。
比 C 简单不知道多少。
int f[310][310][310],b[310][310],a[310310];
void solve(unsigned __testid=1){
int l,n,m;cin>>l>>n>>m;
F(i,1,l)cin>>a[i];
F(i,1,n)F(j,1,m)cin>>b[i][j];
F(i,0,l+1)F(j,0,n+1)F(k,0,m+1)f[i][j][k]=0;
G(i,l,1)G(j,n,1)G(k,m,1){
if(a[i]==b[j][k])f[i][j][k]|=!f[i+1][j+1][k+1];
f[i][j][k]=f[i][j][k]+f[i][j+1][k]+f[i][j][k+1]-f[i][j+1][k+1];
}
if(f[1][1][1])cout<<"T\n";
else cout<<"N\n";
}
E2
咕咕咕。
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18416709,谢谢QwQ