A:直接贪心取即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,x;
cin>>n;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)cin>>x,a[x]++;
int nm=2,n1=0,n2=0;
for(int i=0;i<=100;i++)
{
if(a[i]>1&&nm>1)n2=i+1;
nm=min(nm,a[i]);
if(a[i]>0&&nm>0)n1=i+1;
nm=min(nm,a[i]);
}
cout<<n1+n2<<endl;
}
return 0;
}
B:
dp或直接枚举负数个数更简单。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll a[M];
ll dp[M][6][2];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
ll n,n1=0,n2=0,nm=0,inf=1e15;
cin>>n;
// for(int i=1;i<=n;i++)
// for(int j=1;j<=5;j++)
// dp[i][j][0]=inf,dp[i][j][1]=-inf;
for(int i=1;i<=n;i++)cin>>a[i];
dp[1][1][1]=dp[1][1][0]=a[1];
for(int i=2;i<=n;i++)
{
dp[i][1][0]=min(a[i],dp[i-1][1][0]);
dp[i][1][1]=max(a[i],dp[i-1][1][1]);
for(int j=2;j<=min(5,i);j++)
{
dp[i][j][0]=min(dp[i-1][j-1][0]*a[i],dp[i-1][j-1][1]*a[i]);
if(i>j)dp[i][j][0]=min(dp[i][j][0],dp[i-1][j][0]);
dp[i][j][1]=max(dp[i-1][j-1][0]*a[i],dp[i-1][j-1][1]*a[i]);
if(i>j)dp[i][j][1]=max(dp[i][j][1],dp[i-1][j][1]);
}
}
cout<<dp[n][5][1]<<endl;
}
return 0;
}
C:
两个重心时一定是 最大联通块为n/2的情况,找到重心后破化他们即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
int vs[M],siz[M];
int n,ans,pos;
vector<int>s;
void dfs(int x)
{
vs[x]=1;siz[x]=1;
int mx=0;
for(int i=head[x];i;i=ee[i].nxt)
{
int y=ee[i].to;
if(vs[y])continue;
dfs(y);
siz[x]+=siz[y];
mx=max(mx,siz[y]);
}
mx=max(mx,n-siz[x]);
if(mx<ans)
{
ans=mx;
pos=x;
s.clear();
}
if(mx==ans)s.pb(x);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int u,v;
cin>>n;
for(int i=0;i<=n;i++)head[i]=0,vs[i]=0;
ans=n+1;cnt=1;pos=-1;
for(int i=1;i<n;i++)cin>>u>>v,add(u,v,1),add(v,u,1);
s.clear();
dfs(1);
// cout<<pos<<" "<<ans<<endl;
// for(auto x:s)cout<<" - "<<x;cout<<endl;
if(s.size()==1)cout<<u<<" "<<v<<"\n"<<u<<" "<<v<<endl;
else
{
int p=s[0],q=s[1],t,o;
for(int i=head[p];i;i=ee[i].nxt)
{
int y=ee[i].to;
if(y==q)continue;
t=y;
}
cout<<p<<" "<<t<<endl;
cout<<q<<" "<<t<<endl;
}
}
return 0;
}
D:
假设最大值为x。
令c[1]=x, b[1]=a[1]-x;
然后贪心分配b,c数组。
对于a[j],cz=a[j]-a[j-1]
若cz>0,则为了让b数组尽量小,我们不改变c数组,直接b[j]=b[j-1]+cz;
若cz<0,则为了让b数组尽量小,我们不改变b数组,直接让c[j]=c[j-1]+cz;
上述变化都要满足b非递增,c非递减序列。
然后此时b数组最大的数为b[n]
显然有:b[n]<=c[1]
即:b[1]+zm<=x
即:2*x<=a[1]-zm;
zm为a的差分数组中正数的和。
我们只需要维护zm即可O1求出x
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll a[M],c[M];
ll zm,fm;
void gao(int x,int d)
{
if(c[x]<0)fm-=c[x];else zm-=c[x];
c[x]+=d;
if(c[x]<0)fm+=c[x];else zm+=c[x];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i],c[i]=a[i]-a[i-1];
if(i==1)continue;
if(c[i]>0)zm+=c[i];
else fm+=c[i];
}
// a1=x+y ; x+zm<=y 2x<=a1-zm;
ll ans=a[1]-(a[1]-zm-1)/2;
cout<<ans<<endl;
int q;
cin>>q;
// cout<<" = "<<zm<<" "<<fm<<endl;
while(q--)
{
int l,r,x;
cin>>l>>r>>x;
if(l>1)gao(l,x);
if(r+1<=n)gao(r+1,-x);
// cout<<zm<<" -- "<<fm<<" "<<a[1]<<endl;
if(l==1)a[1]+=x;
ans=a[1]-(a[1]-zm-1)/2;
cout<<ans<<endl;
}
return 0;
}