T1ios
模擬,80? ide
#include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> #include<cmath> #include<ctime> using namespace std; typedef long long LL; const int N=1e5+100; int a[N],n,len; char s[N]; int w[N],maxn; LL f[N],tot; 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]); cin>>(s+1); for(int i=1;i<=n;i++) { w[i]=s[i]-'0'; if(w[i]) maxn=i; } for(int i=1;i<=maxn;i++) { f[i]=f[i-1]; if(a[i]>0) f[i]+=a[i]; } w[0]=1;tot=0; while(maxn>=1) if(w[maxn]) { if(a[maxn]<=0) { cout<<(f[maxn-1]+tot)<<endl; return 0; } tot+=a[maxn]; while(!w[maxn-1]) maxn--; maxn--; } cout<<tot<<endl; return 0; }
#include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> #include<cmath> #include<ctime> using namespace std; typedef long long LL; const int N=1e5+100; int a[N],n,len; char s[N]; int w[N],maxn; LL f[N],tot=0,ans=0; 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]); cin>>(s+1); for(int i=1;i<=n;i++) { w[i]=s[i]-'0'; if(w[i]) maxn=i; } f[0]=0; for(int i=1;i<=maxn;i++) { f[i]=f[i-1]; if(a[i]>0) f[i]+=a[i]; } w[0]=1;tot=0; for(int i=maxn;i>=1;i--) if(w[i]) { // printf("%lld %lld\n",i,tot+f[i-1]); ans=max(ans,tot+f[i-1]); tot+=a[i]; } cout<<ans<<endl; return 0; }
w[0]=1;tot=0;LL all=f[maxn]; while(maxn>=1) { if(a[maxn]<=0) { cout<<(f[maxn-1]+tot)<<endl; return 0; } tot+=a[maxn]; while(!w[maxn-1]) maxn--; maxn--; }
調了半天,我終於發現了錯誤所在。函數
說實話:我錯的真不怨,我感受很高興,由於我找到了本身的思惟誤區。spa
怎麼說呢:最大值可能出如今這些狀況中的任意一個:3d
1除了最高位對應的數外,其餘任意位上數的組合。(最高位是0)
code
2第二高的爲0,其餘的任意位上的數的組合。(最高位是1)blog
3第三高的爲0,其餘位上任意數的組合。(前兩高的是1)ci
............ 這道題中的 最高位 是指 m的二進制位爲1的。string
作的時候還不如取個max那,我只是想固然的認爲:it
當最高位是是負數時,前面的必定比後面的要更優。(這是對的,可是)
我卻認爲這時,不加這個最高位的負數的結果是最優的。
其實否則,這時,對於不加這位的結果前面都算過,這一次卻不必定是最優的!!!!!!
T2
二分+dp
奇怪的貪心。
#include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> #include<cmath> #include<ctime> using namespace std; const int N=1009; int a[N],b[N]; int n,k; int L,R,mid,ans; bool check(int x) { int sum=0,sum0=1e9+1; for(int i=1;i<=n;i++) a[i]=b[i]; a[n+1]=a[n]; for(int i=2;i<=n;i++) { if(abs(a[i]-a[i-1])>x) { if(a[i]>a[i-1]) { a[i]=a[i-1]+x; sum++; }else if(a[i-1]>a[i]) { a[i]=a[i-1]-x; sum++; } } } int i=1,j=n; for(int i=1;i<=n;i++,j--) a[i]=b[j]; a[n+1]=a[n]; for(int i=2;i<=n;i++) { if(abs(a[i]-a[i-1])>x) { if(a[i]>a[i-1]) { a[i]=a[i-1]+x; sum0++; }else if(a[i-1]>a[i]) { a[i]=a[i-1]-x; sum0++; } } } sum=min(sum,sum0); return sum<=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",&b[i]); R=max(R,b[i]); } if(k>=n-1) { cout<<0<<'\n'; return 0; } L=0,R; while(L<=R) { mid=(L+R)/2; if(check(mid)) R=mid-1,ans=mid; else L=mid+1; } cout<<ans<<'\n'; return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; int n,k; int a[2000],f[2000]; int L,R,mid; bool check(int x) { f[1]=0; int ans=n;//最大不超過n for(int i=2;i<=n;i++) { f[i]=i; 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)); ans=min(ans,f[i]+n-i); } return ans<=k; } int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&a[i]); L=0,R=1e9+19; while(L<R-1) { mid=(L+R)>>1; if(check(mid)) R=mid; else L=mid; } if(check(L)) printf("%d\n",L); else printf("%d\n",R); return 0; }
T3
#include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<cstdio> #include<cmath> #include<ctime> using namespace std; const int N=1e3+10; char s[N]; int n,x,y,len; int q,l,r; int A[N],B[N]; bool ok[N][N]; int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); scanf("%d%d%d",&n,&x,&y); cin>>(s+1); for(int i=1;i<=n;i++) { A[i]=A[i-1];B[i]=B[i-1]; if(s[i]=='A') A[i]++; else B[i]++; } for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) { int Asum,Bsum; Asum=A[j]-A[i-1];Bsum=B[j]-B[i-1]; if(1LL*Asum*y==1LL*Bsum*x) ok[i][j]=1; } scanf("%d",&q); while(q--) { scanf("%d%d",&l,&r); int L=r-l+1; for(L;L>=1;L--) for(int i=l;i+L-1<=r;i++) if(ok[i][i+L-1]) { printf("%d\n",L); L=0,i=r+3;break; } } return 0; }
待續。。。。。。
1用和爲0,判斷,鏈表查詢,O( n q)。
2分塊。
3可持久線段樹。。。難寫。
最短 函數線段樹