专栏文章
P14082 题解
P14082题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minrsysq
- 此快照首次捕获于
- 2025/12/02 07:18 3 个月前
- 此快照最后确认于
- 2025/12/02 07:18 3 个月前
引言
标签:数学贪心
正文
题目给出一个长度为的字符串
要求切刀将其分为段连续非空子串
若分不出段,则代表你无法分割
求最终可以有多少种可能的价值
大致思路:
直接求出价值的可能最低点和可能最高点
即价值的取值区间
如何求价值区间
可以把原本的字符串的价值先求出
初始价值可以这么计算:
价值=每个字母的分界处数量+1
例如样例中的:
aaabbc可以找到
- 分界点 的分界
- 分界点 的分界
即有个不同字母的串,价值为
可以用循环实现
-
若第刀切在分界点上,那么总价值不增加
-
若第刀切在非分界点上,那么总价值
初步计算
最小值取值=初始价值切完刀后增长的最小价值
最大值取值=初始价值切完刀后增长的最大价值
总共的价值数量最大值最小值
即总共的价值数量切完刀后增长的最大价值-切完刀后增长的最小价值
计算切完刀后增长的最大价值
则使尽量每一刀都切在非分界点上
计算得最大价值=刀数-(字符长-1-分界点数)
计算切完刀后增长的最小价值
则使尽量每一刀都切在分界点上
计算得最小价值=刀数-分界点数
到这就可以开始实现代码了
代码实现
CPP#include <bits/stdc++.h>
using namespace std;
signed main(){
int k,n;
cin>>n>>k;
if(k+1>n){
cout <<0;
return 0;
}//若无法分为k+1份,输出0
string s;
cin>>s;
char noww=s[0];//记录上一个字符
int size_=s.size(),cs=1;//长度和初始价值
for(int i=1;i<size_;i++){
if(noww!=s[i]){
cs++;
noww=s[i];
}
}
int fjd=cs-1;//分界点
int more=max(k-fjd,0);
int l=cs+more;
int less=n-1-fjd,aaa=0;
if(less<k)aaa=k-less;
//若非分界点数小于刀数,统计最高上限的限制
int r=cs+k-aaa;//最高-限制
cout <<r-l+1;//统计区间
return 0;
}
无注释版
CPP#include <bits/stdc++.h>
using namespace std;
signed main(){
int k,n;
cin>>n>>k;
if(k+1>n){
cout <<0;
return 0;
}
string s;
cin>>s;
char noww=s[0];
int sz=s.size(),c=1;
for(int i=1;i<sz;i++){
if(noww!=s[i]){
cs++;
noww=s[i];
}
}
int f=c-1;
int more=max(k-f,0);
int l=c+more;
int ls=n-1-f,a=0;
if(ls<k)a=k-ls;
int r=c+k-a;
cout <<r-l+1;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...