646 字
2 分钟
CF1398

A. Bad Triangle#

给一个非递减数组,问是否存在三个下标对应数组元素无法构成三角形。

由于非递减,则第一、二个元素为最小,若最大元素即最后一个元素可以构成三角形,则不存在无法构成三角形的三个下标;反之则取第一、二和最后一个元素即可。

void solve(){
int n;cin>>n;
vector<int> a(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
if(a[0]+a[1]>a[n-1])cout<<-1<<endl;
else cout<<"1 2 "<<n<<endl;
}

B. Substring Removal Game#

有一 01 字符串,每次可以删除一段连续相同的子串,得分为删除的 1 的数量,问先手得到的最大得分。

易得,删除 0 是劣的,若删除 0 后两侧的 1 相连,则下家可以一次性获得原本两侧需要两次的分数;若删除 0 后两侧的 1 不相连,则本次操作没有意义。 即两人均不会删除任意 0。 两人每次的得分只能是原本就相连的 1 的数量。统计连续的 1 的数量,从大到小贪心选择,奇数位的得分即为先手得分。

void solve(){
string s;cin>>s;
int n=s.size();
vector<int> cnt;
int now=(int)(s[0]=='1');
for(int i=1;i<n;i++){
if(s[i]=='1'){
if(s[i-1]=='0') now=1;
else now++;
}else{
if(s[i-1]=='1') cnt.push_back(now);
now=0;
}
}
cnt.push_back(now);
sort(cnt.rbegin(),cnt.rend());
int ans=0;
for(int i=0;i<cnt.size();i+=2){
ans+=cnt[i];
}
cout<<ans<<endl;
}

C. Good Subarrays#

给定一由 0-9 的整数组成的数组,问有多少好子数组满足数组元素和等于数组长度。

设原数组为 a[n],则好数组 a[l,r] 满足 i=lrai=rl+1    i=lr(ai1)=0\sum_{i=l}^r a_{i} = r-l+1 \implies \sum_{i=l}^r (a_i-1) = 0 设数组 b[n]b[i]=a[i]-1,求 b[n] 的前缀和 pre[n],满足 pre[r]-pre[l-1]=0 的位置即为所求位置,用 map 保存不同前缀和的位置,即可快速求出数量。

void solve(){
int n;cin>>n;
string s;cin>>s;
vector<int> a(n),pre(n);
map<int,int> precnt;
for(int i=0;i<n;i++) a[i]=s[i]-'0'-1;
pre[0]=a[0];
precnt[pre[0]]++;
for(int i=1;i<n;i++){
pre[i]=a[i]+pre[i-1];
precnt[pre[i]]++;
}
int ans=precnt[0];
for(auto [_,it]:precnt){
ans+=(it*(it-1)/2);
}
cout<<ans<<endl;
}

D. Colored Rectangles#

分别有 R,G,BR,G,B 对颜色为红、绿、蓝色的小棒,给定每对小棒的长度,每次取颜色不同的两对小棒组成矩形,问组成的所有矩形的面积和最大为多少。

显然对于同色小棒来说,优先取长度长的小棒,故先由大到小排序。 设 dp[i][j][k] 为用了前 i 对红色小棒,前 j 对绿色小棒,前 k 对蓝色小棒后可以达到的最大面积。 状态转移见程序。

signed main(){
int R,G,B;cin>>R>>G>>B;
vector<int> r(R+1),g(G+1),b(B+1);
for(int i=0;i<R;i++)cin>>r[i];
for(int i=0;i<G;i++)cin>>g[i];
for(int i=0;i<B;i++)cin>>b[i];
sort(r.rbegin(),r.rend());
sort(g.rbegin(),g.rend());
sort(b.rbegin(),b.rend());
vector<vector<vector<int>>> dp(R+1,vector<vector<int>>(G+1,vector<int>(B+1)));
int ans=0;
for(int i=0;i<=R;i++){
for(int j=0;j<=G;j++){
for(int k=0;k<=B;k++){
if(i<R&&j<G)dp[i+1][j+1][k]=max(dp[i][j][k]+r[i]*g[j],dp[i+1][j+1][k]);
if(i<R&&k<B)dp[i+1][j][k+1]=max(dp[i][j][k]+r[i]*b[k],dp[i+1][j][k+1]);
if(j<G&&k<B)dp[i][j+1][k+1]=max(dp[i][j][k]+g[j]*b[k],dp[i][j+1][k+1]);
ans=max(ans,dp[i][j][k]);
}
}
}
cout<<ans<<endl;
return 0;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

CF1398
https://leaf146.cn/posts/cf1398
作者
LeAf146
发布于
2026-07-08
许可协议
MIT

部分信息可能已经过时