T1
贪心模拟
从右往左,遇见m是1的位,有选或者不选两种操作:如果这一位是负数,那肯定不选更优,把这一位的二进制看做0,那么前面就可以任意选;如果选,那么sum+a[i],继续向前扫。
T2
二分答案 +DP
二分两个数之间的差的最大值
F[i]表示i不改变的最小修改的元素个数
f[i] = min(f[j] +(i-j-1), i-1) abs(A[j]-A[i]) < 二分出来的答案*(i-j)
T3
再留个坑。
T1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int N=100009;
int n,a[N],k[N];
LL ans,q[N];
char c[N];
int main()
{
freopen("maximum.in","r",stdin);
freopen("maximum.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("\n");
gets(c);
int len=strlen(c);
for(int i=0;i<len;i++) k[i+1]=c[i]-'0';
while(!k[len]) len--;
n=min(len,n);
for(int i=1;i<=n;i++)
{
q[i]=q[i-1];
if(a[i]>0) q[i]+=a[i];
}
if(len>n)
{
ans=q[n];
}
else//n==len
{
LL sum=0;
for(int i=len;i>=1;i--)
{
if(k[i])
{
LL s=sum+q[i-1];
ans=max(ans,s);//不选
if(a[i]<=0) break;
sum+=a[i];
}
}
ans=max(ans,sum);
}
printf("%lld\n",ans);
return 0;
}
T2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int N=1009;
const int inf=1e9+7;
int n,k,a[N],f[N];
bool check(int x)
{
f[1]=0;
int s=n;
for(int i=2;i<=n;i++)
{
f[i]=i-1;
for(int j=1;j<=n;j++)
if(abs(a[i]-a[j])<=1ll*x*(i-j))
f[i]=min(f[j]+i-j-1,f[i]);
s=min(s,f[i]+n-i);
}
return s<=k;
}
int main()
{
//freopen("minimum.in","r",stdin);
//freopen("minimum.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int L=0,R=inf,ans=inf,mid;
while(L<=R)
{
mid=(L+R)>>1;
if(check(mid)) ans=mid,R=mid-1;
else L=mid+1;
}
printf("%d",ans);
return 0;
}