CF1373D. Maximum Sum on Even Positions (最大字段和)
链接:https://codeforces.com/contest/1373/problem/D
题意:给定一个长度为 n 的数组。你可以选择一个连续区间 [ l , r ] [l,r] [l,r],将这个区间翻转,最多翻转一次。问奇数位的和最大是多少?
思路:首先翻转必然是选择偶数个数,不然对答案无影响。
- 对答案产生影响只有两种情况,一种是偶数位和前面的奇数位,另一种是偶数位和后面的奇数产生影响。
- 然后就变成了一个最大连续子段和的问题。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10;
int t,n,a[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
ll ans1=0,ans2=0;
for(int i=1;i<=n;i+=2) ans1+=a[i];
for(int i=1;i<=2;++i)
{
vector<int> vec;
for(int j=i+1;j<=n;j+=2)
{
if(i==1) vec.push_back(a[j]-a[j-1]);
else vec.push_back(a[j-1]-a[j]);
}
ll sum=0,m=vec.size();
ll res=0;
for(int j=0;j<m;++j)
{
sum+=vec[j];
res=max(res,sum);
if(sum<0) sum=0;
}
ans2=max(ans2,res);
}
printf("%lld\n",ans1+ans2);
}
return 0;
}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+10,maxm=5e5+10;
int t,n;
ll a[maxn],b[maxn];
int main()
{
cin>>t;
while(t--)
{
cin>>n;
ll res=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
if(i%2==1) res+=a[i];
}
for(int i=1;i<=n;++i)
{
if(i%2==1) a[i]*=-1;
b[i]=b[i-1]+a[i];
}
ll ans=0;
for(int s=1;s<=2;++s)
{
ll mi=0;
for(int i=s;i<=n;i+=2)
{
ans=max(ans,b[i]-mi);
mi=min(mi,b[i]);
}
}
printf("%lld\n",ans+res);
}
return 0;
}
CF1330C. Dreamoon Likes Coloring (思维 + 贪心)
链接:https://codeforces.com/contest/1330/problem/C
题意:给定 n n n 个格子,有 m m m 次染色操作,每次将连续 l i l_i li 个格子染成颜色 i ,要求最后每种颜色都能看到,且每个格子都被染色。请你输出每次染色的起点 p i p_i pi
思路:先将起点设在 [ 1 ,m],然后在拉伸填充空位。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5,inf=1e9;
int n,m;
int l[maxn],p[maxn];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=m; ++i) scanf("%d",&l[i]);
bool ok=1;
ll sum=0;
for(int i=1; i<=m; ++i)
{
p[i]=i;
sum+=l[i];
if(i+l[i]-1>n) ok=0;
}
if(!ok||sum<n)
{
puts("-1");
return 0;
}
p[m+1]=n+1;
for(int i=m; i>=1; --i)
{
if(p[i]+l[i]>=p[i+1]) break;
p[i]=p[i+1]-l[i];
}
for(int i=1; i<=m; ++i)
printf("%d%c",p[i],i==m?'\n':' ');
return 0;
}