清北刷题冲刺 11-02 p.m

函数最值

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int n;
long long a[maxn],ans,sum[maxn];
char s[maxn];
long long qread(){
    int i=0,j=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
    while(ch<='9'&&ch>='0')i=i*10+ch-'0',ch=getchar();
    return i*j;
}
int main(){
    freopen("maximum.in","r",stdin);freopen("maximum.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        a[i]=qread();
        sum[i]=sum[i-1];
        if(a[i]>0)sum[i]=sum[i-1]+a[i];
    }
    scanf("%s",s+1);
    long long c=0;
    for(int i=n;i>=1;i--)//枚举从哪一位开始 
        if(s[i]=='1'){
            ans=max(ans,c+sum[i-1]);
            c+=max(a[i],0LL);
        }
    ans=max(ans,c);
    cout<<ans;
}
100分 贪心

 

 

函数最值2

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1010
using namespace std;
int n,k,a[maxn],pla[10000000],cnt,b[maxn];
long long ans=1000000000000000;
int count(int x){
    int res=0;
    while(x){
        if(x&1)res++;
        x>>=1;
    }
    return res;
}
bool pos[maxn];
long long Abs(long long x){
    if(x>=0)return x;
    if(x<0)return -x;
}
int main(){
    freopen("minimum.in","r",stdin);freopen("minimum.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d%d",&n,&k);
    for(int i=0;i<(1<<n);i++)
        if(count(i)==k)pla[++cnt]=i;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=cnt;i++){
        memset(pos,0,sizeof(pos));
        int p=0;
        int now=pla[i];
        while(now){
            p++;
            if(now&1)pos[p]=1;
            now>>=1;
        }
        for(int j=1;j<=n;j++){
            if(pos[j]==0||j==1)b[j]=a[j];
            else b[j]=b[j-1];
        }
        long long sum=0;
        for(int j=2;j<=n;j++){
            sum=max(sum,Abs(b[j]-b[j-1]));
        }
        ans=min(ans,sum);
    }
    cout<<ans;
}
20分 暴力
/*
    二分两个数之间的差的最大值
    F[i]表示i不改变的最小修改的元素个数
    f[i]=min(f[j]+(i-j-1),i-1) abs(A[j]-A[i])<二分出来的答案*(i-j)
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#define maxn 2010
using namespace std;
int n,k,a[maxn],f[maxn];
bool check(int x){
    f[1]=0;
    int ans=n;
    for(int i=2;i<=n;i++){
        f[i]=i-1;
        for(int j=1;j<i;j++)
            if(abs(a[i]-a[j])<=1LL*x*(i-j))
                f[i]=min(f[i],f[j]+(i-j-1));//假设改了(j~i)的数 
        ans=min(ans,f[i]+n-i);//假设最后一个数改了 
    }
    return ans<=k;
}
int main(){
    freopen("minimum10.in","r",stdin);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int l=0,r=1000000001,ans=1000000001;
    while(l<=r){
        int mid=(l+r)>>1;
        if(check(mid))ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d",ans);
    return 0;
}
100分 二分+dp

 

 

 

序列

 

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 100010
using namespace std;
int n,X,Y,sum[maxn];
bool ok[1010][1010];
char s[maxn];
int Gcd(int x,int y){
    if(y==0)return x;
    return Gcd(y,x%y);
}
int main(){
    freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);
//    freopen("Cola.txt","r",stdin);
    scanf("%d%d%d",&n,&X,&Y);
    scanf("%s",s+1);
    for(int i=1;i<=n;i++){
        sum[i]=sum[i-1];
        if(s[i]=='A')sum[i]=sum[i-1]+1;
    }
    for(int len=1;len<=n;len++){//枚举长度 
        for(int l=1;l+len-1<=n;l++){
            int r=l+len-1;
            int cntA=sum[r]-sum[l-1];
            int cntB=len-cntA;
            int g=Gcd(cntA,cntB);
            cntA/=g;cntB/=g;
            if(cntA==X&&cntB==Y)ok[l][r]=1;
        }
    }
    int q;
    scanf("%d",&q);
    int l,r,ans;
    while(q--){
        scanf("%d%d",&l,&r);
        bool flag=0;
        for(int len=r-l+1;len>=0;len--){
            for(int i=l;i+len-1<=r;i++){
                int j=i+len-1;
                if(ok[i][j]){
                    ans=len;
                    flag=1;
                    break;
                }
            }
            if(flag)break;
        }
        printf("%d\n",ans);
    }
}
25分 暴力

 

 

 

 

 

预计得分100+30+30
实际得分100+20+25
T1写了一个小时的数位dp,然后调不出来了,发现可以贪心,就写了贪心。T2T3看了没什么思路,T2前30分可以状压,T330分貌似爆搜就能过,可能代码写的丑
今天的暴力分都得的不全,希望能把暴力写的优美一点
小结

 

posted @ 2017-11-02 17:01  Echo宝贝儿  阅读(178)  评论(0编辑  收藏  举报