CF Round #625
CF Round#625
A.水题
B.数学##
理解题意后,脑袋一下就想到,诶,dp,可是又一看数据范围,O(n2)做法直接TLE。
那么我们该怎么想这道题嘞?
仔细想想看恒等式是个什么东西,我们好像不难发现,如果建立以b,c坐标轴的坐标系(Ci指的是C序列位置为i的数是几,Bi,指的就是这个C序列中的i),那么对于任意两个点而言,如果他们之间满足上式成立,那么他们的斜率为1。而我们又知道,斜率为1的直线,c-b的值是唯一确定的,那么我们不妨开一个数组记录累加这些点对于的c值,取他们的最大值即是答案。有个细节值得注意c-b可能<0哦
AC代码:
#include<iostream>
#include<cstring>
using namespace std;
#define INF 1e10+5
#define MAXN 400005
#define MINN -105
typedef long long int LL;
LL max(LL a,LL b)
{
return a>b?a:b;
}
int main()
{
int n;
LL a[MAXN<<1];
LL b;
LL ans=0;
memset(a,0,sizeof(a));
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>b;
a[b-i+MAXN]+=b;
ans=max(ans,a[b-i+MAXN]);
}
cout<<ans<<endl;
return 0;
}
C贪心,模拟##
题意
给出字符串 s,1≤∣s∣≤100。
定义一次变换为,选中第 i 个字符移除,字符串长度减少 1,选中字符需要满足 i+1或者i-1是它的字典序前驱,求最多操作几次
e.g.
input:8 bacabcab output:4
分析
从大到小贪心即可,即z->a去模拟删除(数据很弱),可以掏出vector实现链表
不过值得注意的点是
可能会有类似bbbbbbbbbbbbbaaabbbbbbbbbbb这样的出现,所以每次遍历字符串进行删除操作的时候,每个迭代里面自右向左还要扫一次,否则前面的b没删够
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
#define INF 1e10+5
#define MAXN 105
#define MINN -105
typedef long long int LL;
int main()
{
int n;
char a;
cin>>n;
vector<char>line;
vector<char>::iterator it;
for(int i=1;i<=n;i++)
{
cin>>a;
line.push_back(a);
}
int ans=0;
for(int p=0;p<=199;p++)
for(int i='z';i>=97;i--)
{
for(it=line.begin();it!=line.end();it++)
{
if(*it==i)
{
bool ok=0;
if(it!=line.begin())if(*(it-1)==i-1)ok=1;
if((it+1)!=line.end())if(*(it+1)==i-1)ok=1;
if(ok)
{
line.erase(it),ans++;
if(it!=line.begin())it--;
}
}
}
for(it=line.end()-1;it!=line.begin()-1;it--)
if(*it==i)
if(*it==i)
{
bool ok=0;
if(it!=line.begin())if(*(it-1)==i-1)ok=1;
if((it+1)!=line.end())if(*(it+1)==i-1)ok=1;
if(ok)
{
line.erase(it),ans++;
if(it!=line.end()-1)it++;
}
}
}
cout<<ans<<endl;
return 0;
}