北京集训DAY3

来源:互联网 发布:linux查看内存位置 编辑:程序博客网 时间:2024/05/01 07:13

 1 /* 2     消去合法的序列 剩下的不合法序列一定是 ))....(((... 3     两种括号个数各加1除2  手算一下即可 4 */ 5 #include <cctype> 6 #include <cstdio> 7 #include <cstring> 8  9 const int MAXN=100010;10 11 int len,top,cnt;12 13 char s[MAXN];14 15 int hh() {16     freopen("bracket.in","r",stdin);17     freopen("bracket.out","w",stdout);18     scanf("%s",s+1);19     len=strlen(s+1);20     for(int i=1;i<=len;++i) {21         if(s[i]=='(') ++top;22         else if(s[i]==')'&&top) --top;23         else ++cnt;24     }25     int ans=(top+1)/2+(cnt+1)/2;26     printf("%d\n",ans);27     fclose(stdin);28     fclose(stdout);29     return 0;30 }31 32 int sb=hh();33 int main(int argc,char**argv) {;}
题解

 1 /* 2     维护一个f数组 f[i]表示i这个时刻  车上已经坐了几只怪兽了 3     [X,Y] Z 4     for (int i=X; i<Y; i++) 5           MAX=max(MAX,f[i]); 6     t=min(Z,M-MAX); 7     for (int i=X; i<Y; i++) f[i]+=t; 8     ans+=t 9     cout<<ans;10     显然 可用线段树维护区间加和区间查询最大值11 */12 #include<iostream>13 #include<cmath>14 #include<cstdio>15 #include<cstring>16 #include<algorithm>17 #define N 5000518 #define lson (root<<1)19 #define rson (root<<1|1)20 #define Max(a,b) a=a>b?a:b21 using namespace std;22 23 int k,n,m,x,y,ans,tmp,val;24 25 int tree[N<<2],mark[N<<2];26 27 struct Node{28     int l,r,peo;29     bool operator <(const Node &a)const {30         if(a.r!=r)return r<a.r;31         return l>a.l;32     }33 }node[N];34 35 inline int qread() {36     int x=0,j=1;37     char ch=getchar();38     while(ch<'0' || ch>'9'){if(ch=='-')j=-1;ch=getchar();}39     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}40     return x*j;41 }42 void pushdown(int root) {43     if(!mark[root]) return;44     int k=mark[root];45     tree[lson]+=k;tree[rson]+=k;46     mark[lson]+=k;mark[rson]+=k;47     mark[root]=0;48 }49 int query(int root,int l,int r,int L,int R) {50     if(l>R||r<L)return 0;51     if(L<=l&&r<=R)return tree[root];52     int mid=(l+r)>>1;53     pushdown(root);54     int a=query(lson,l,mid,L,R),b=query(rson,mid+1,r,L,R);55     tree[root]=Max(tree[lson],tree[rson]);56     return Max(a,b);57 }58 void updata(int root,int l,int r,int L,int R,int to) {59     if(l>R||r<L) return;60     if(L<=l&&r<=R) {61         mark[root]+=to;62         tree[root]+=to;63         return;64     }65     pushdown(root);66     int mid=(l+r)>>1;67     updata(lson,l,mid,L,R,to);68     updata(rson,mid+1,r,L,R,to);69     tree[root]=Max(tree[lson],tree[rson]);70 }71 int main() {72     freopen("bus.in","r",stdin);73     freopen("bus.out","w",stdout);74     k=qread();n=qread();m=qread();75     for(int i=1;i<=k;i++) {76         node[i].l=qread();77         node[i].r=qread();78         node[i].peo=qread();79     }80     sort(node+1,node+k+1);81     for(int i=1;i<=k;i++) {82         tmp=query(1,1,n,node[i].l,node[i].r);83         if(tmp>=m)continue;84         if(tmp+node[i].peo<=m) val=node[i].peo;85         else val=m-tmp;86         ans+=val;87         updata(1,1,n,node[i].l,node[i].r-1,val);88     }89     printf("%d\n",ans);90     fclose(stdin);fclose(stdout);91     return 0;92 }
题解

 1 /* 2     枚举左上角 n^2  枚举右下角n^2  枚举修改的数  n^2  求和 n^2  ->  n^8 3     求一个矩阵和,可以通过矩阵前缀和做到O(1) 4     枚举左上角 n^2  枚举右下角n^2  枚举修改的数  n^2   ->  n^6 5     预处理出每个矩阵的最小值是多少。   n^4 6     枚举左上角 n^2  枚举右下角n^2  修改的数已知(修改最小的或者不修改)  -》n^4  7     n,m<=300   8     假如我们不要求修改数,查询最大子矩阵   9     有n个数,查询最大子段和  O(n)10     for (i=1; i<=n; i++) f[i]=max(f[i-1]+a[i],a[i]);11     max{f[i]} = 最大子段和12     要求我们修改数13     修改的数一定是最小的那个数。14     f[i][0]以i结尾并且没有数被修改过的最大和15     f[i][1]以i结尾并且有数被修改过的最大和  //a[i]  第i列的和16     for (int i=1; i<=n; i++)17     {    18           f[i][0]=max(f[i-1][0]+a[i],a[i]);19       f[i][1]=max(f[i-1][1]+a[i],f[i-1][0]+a[i]-MIN[i]+P,a[i]-MIN[i]+P);20     }21     max{f[?][0/1]} 是答案22 */23 #include <cmath>24 #include <cstdio>25 #include <cstdlib>26 #include <cassert>27 #include <algorithm>28 29 const int INF=1000000000;30 const int MAXN=305;31 32 int n,m,ans,P,k;33 34 int a[MAXN][MAXN],MIN[MAXN],b[MAXN],dp[MAXN][2],s[MAXN][MAXN];35 36 inline int min(int a,int b) {37     return a>b?b:a;38 }39 40 inline int max(int a,int b) {41     return a>b?a:b;42 }43 44 int hh() {45     freopen("puzzle.in","r",stdin);46     freopen("puzzle.out","w",stdout);47     while(scanf("%d",&n)) {48         ans=-INF;49         scanf("%d%d",&m,&P); assert(1<=n&&n<=300&&1<=m&&m<=300&&-1000<=P&&P<=1000);50         for(int i=1;i<=n;i++)51           for(int j=1;j<=m;j++) {scanf("%d",&a[i][j]); assert(-1000<=a[i][j]&&a[i][j]<=1000); }52         for(int i=1;i<=n;i++)53           for(int j=1;j<=m;j++)54             s[i][j]=s[i-1][j]+a[i][j];55         for(int i=1;i<=n;i++) {56             for(int j=1;j<=m;j++) MIN[j]=a[i][j];57             for(int j=i;j<=n;j++) {58                 for(int k=1;k<=m;k++) MIN[k]=min(MIN[k],a[j][k]);59                 for(int k=1;k<=m;k++) b[k]=s[j][k]-s[i-1][k];60                 dp[0][1]=-INF;61                 for(int k=1;k<=m;k++) dp[k][0]=max(dp[k-1][0]+b[k],b[k]),dp[k][1]=max(max(dp[k-1][1]+b[k],dp[k-1][0]+b[k]-MIN[k]+P),b[k]-MIN[k]+P);62                 for(int k=1;k<m;k++) ans=max(ans,max(dp[k][0],dp[k][1]));63                 if(i==1&&j==n) {64                     ans=max(ans,dp[m][1]);65                     int sum=0;66                     for(int k=m; k>1; k--) {sum+=b[k]; ans=max(ans,sum);}67                 } else68                   ans=max(ans,max(dp[m][1],dp[m][0]));69             }70         }71         printf("%d\n",ans);72     }73     return 0;74 }75 76 int sb=hh();77 int main(int argc,char**argv) {;}
题解