C. Little Girl and Maximum Sum
难度 1500
一开始题意没读懂,以为是个简单的dp:每次用长度为r-l+1的最大子段和相加。
后来发现就是个差分而已。
题意:给定长度为n的数列,询问m次l到r区间的和,要求所有询问结果的和最大
思路:差分处理出现频率,频率最高的对应数值最大的
#include <iostream>
#include <algorithm>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <stdio.h>
using namespace std;
#define int long long
const int N = 2e5+10;
int a[N];
int p[N];
inline bool cmp(int a,int b)
{
return a>b;
}
signed main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
int l,r;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld",&l,&r);
p[l]++;
p[r+1]--;
}
for(int i=1;i<=n;i++)
{
p[i]+=p[i-1];
}
sort(a+1,a+1+n,cmp);
sort(p+1,p+1+n,cmp);
int ans=0;
for(int i=1;i<=n;i++)
{
ans+=p[i]*a[i];
}
cout<<ans<<endl;
return 0;
}
C. Palindrome Transformation
难度1700
题意:给定字符串和光标初始位置,花费为光标移动距离和改变当前光标字符值(b到d花费是2,a到z花费可以是25也可以是1),求让原字符串回文的最小花费。
思路:细节比较多,首先让p先固定在左边一半,然后找出左边一半要改变位置的最大和最小下标,字符串字符改变的花费很容易统计,主要是后面要分类讨论移动的花费。
#include <iostream>
#include <cmath>
using namespace std;
const int N=1e5+5;
char s[N];
int cnt=0;
int main()
{
int n,p;
cin>>n>>p;
cin>>s+1;
int ans=0;
int maxx=-1,minn=1e9;
if(p>n/2)
{
p=n-p+1;
}
for(int i=n/2;i>=1;i--)
{
if(s[i]!=s[n-i+1])
{
//cout<<i<<" "<<n-i+1<<" "<<abs(s[i]-s[n-i+1])<<endl;
ans+=min(abs(s[i]-s[n-i+1]),26-abs((s[i]-s[n-i+1])));
minn=min(minn,i);
maxx=max(maxx,i);
}
}
//cout<<ans<<" "<<maxx<<" "<<minn<<endl;
if(ans==0)
{
cout<<0<<endl;
return 0;
}
if(p<=minn)
{
cout<<ans+(maxx-p)<<endl;
}
else if(p>=maxx)
{
cout<<ans+(p-minn)<<endl;
}
else
{
if(abs(p-minn)>=abs(p-maxx))
{
cout<<ans+(p-minn)+(maxx-p)*2<<endl;
}
else
{
cout<<ans+(p-minn)*2+(maxx-p)<<endl;
}
}
return 0;
}