10.19考试总结

来源:互联网 发布:蓝月英雄翅膀升级数据 编辑:程序博客网 时间:2024/06/06 00:39
说实话今天真的不想写总结,又一次被t1坑惨了,莫名re,然后各种脑残结论看不出来。
1.刮刮卡
    题目大意:给一组数,可以将前面任意个数拿到后面去,问要连续得分最大,且每加上一个数时不能为负时,把前多少个移走(所有数和为0)。
      感想:想了一个小时看不出来,于是打了个暴力,花了1个小时写了t2,t3的暴力自认为稳拿90,便回来写t1,这样就有190还是看的过去,结果没看出结论,打了个单调队列,莫名re,然后重新打了一遍(考试时打的太丑),结果就过了,很稳。其实不难看出这样一个结论,前缀和最小的地方一定是该移动的地方,然后for一遍gg。下面是我写的单调队列,可以参考参考。
//我都不知道怎么就过了。//也不知道考试怎么就莫名re # include <iostream># include <cstdio># include <cstring># include <algorithm># include <cmath># include <list>using namespace std;int read(){int f=1,i=0;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){i=(i<<3)+(i<<1)+ch-'0';ch=getchar();}return f*i;}int a[2000005],sum[4000005],n,x;int main(){freopen("lx.in","r",stdin);n=read();for(int i=1;i<=n;++i) a[i]=read();for(int i=1;i<=n;++i){x=read();sum[i]=sum[i-1]+a[i]-x;sum[i+n]=sum[i];}list<int >tmp;int ans=0,id;for(int i=1;i<=n*2;++i){while(!tmp.empty()&&i-tmp.back()>n) tmp.pop_back();while(!tmp.empty()&&sum[i]-sum[tmp.front()]<0) tmp.pop_front();tmp.push_front(i);if(sum[i]-sum[tmp.back()-1]>ans) {ans=sum[i]-sum[tmp.back()-1];id=tmp.back();}} cout<<id<<endl;}
2.矩阵
    题目大意:给一个n*2的矩阵(前%50是n*1),求选k个子矩阵的最大和,子矩阵不能相交。
      感想:因为t1没想出来,所以很慌,半小时打了个暴力就过了,感觉很划算的样子。正解:定义一个dp[i][j][k],表示第一列前i段,第二例前j段中选k个矩阵的最优解,然后分三种情况转移就好了。还有一种(nk)的方法,轮廓线dp,有兴趣可以去看一下,因为我还是不会的;
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<ctime>#include<algorithm>using namespace std;const int N=200;int s[N][5],f2[N][N][N],f[N][N];int n,m,k,ans;void work1(){int f[N][N];memset(f,128,sizeof(f));for(int i=0;i<=n;i++)f[i][0]=0;for(int i=1;i<=n;i++)for(int j=1;j<=k;j++){f[i][j]=f[i-1][j];for(int t=0;t<=i-1;t++)f[i][j]=max(f[i][j],f[t][j-1]+s[i][1]-s[t][1]);}    ans=f[n][k];    return ;}void cz(){memset(f2,128,sizeof(f2));for(int i=0;i<=n;i++)    for(int j=0;j<=n;j++) f2[i][j][0]=0;for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)        for(int t=1;t<=k;t++)        {    f2[i][j][t]=max(f2[i-1][j][t],f2[i][j-1][t]);    for(int p=0;p<=i-1;p++)        f2[i][j][t]=max(f2[i][j][t],f2[p][j][t-1]+s[i][1]-s[p][1]);    for(int p=0;p<=j-1;p++)        f2[i][j][t]=max(f2[i][j][t],f2[i][p][t-1]+s[j][2]-s[p][2]);    if(i==j)        for(int p=0;p<=i-1;p++)            f2[i][j][t]=max(f2[i][j][t],f2[p][p][t-1]+s[i][1]-s[p][1]+s[i][2]-s[p][2]);        }ans=f2[n][n][k];return ;}int main(){//freopen("k.in","r",stdin);//freopen("k.out","w",stdout);cin>>n>>m>>k;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cin>>s[i][j];s[i][j]+=s[i-1][j];}if(m==1)work1();if(m==2)cz();cout<<ans;return 0;}
3.剪裁表格
    题目大意:给你一个矩阵,每次询问任意两个相等且不相交的子矩阵,把它们交换位置,输出最后的矩阵
      感想:(n*m*q)暴力80分,加个register可以卡过。写平衡树还会慢些。当然题解肯定不能这样,solution上是这么说的,用一个四向链表维护一下ok。。。我没看懂,只有附上代码了,事实上暴力比正解跑的快一些。
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>#define ll long longusing namespace std;int getint(){int i=0,f=1;char c;for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());if(c=='-')f=-1,c=getchar();for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';return i*f;}const int N=1005;int n,m,Q,num;int f[N*N][2],lab[N][N],v[N*N];int getlab(int a,int b){int p=lab[0][0];for(int i=1;i<=a;i++)p=f[p][1];for(int i=1;i<=b;i++)p=f[p][0];return p;}int main(){//freopen("lx.in","r",stdin);//freopen("table.out","w",stdout);int a,b,c,d,h,w;n=getint(),m=getint(),Q=getint();for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)v[lab[i][j]=++num]=getint();for(int i=0;i<=m+1;i++)lab[0][i]=++num,lab[n+1][i]=++num;for(int i=1;i<=n;i++)lab[i][0]=++num,lab[i][m+1]=++num;for(int i=0;i<=n;i++)for(int j=0;j<=m;j++){f[lab[i][j]][0]=lab[i][j+1];f[lab[i][j]][1]=lab[i+1][j];}while(Q--){a=getint(),b=getint(),c=getint(),d=getint(),h=getint(),w=getint();int p1=getlab(a-1,b-1),p2=getlab(c-1,d-1);int t1,t2,ww,hh;for(t1=p1,t2=p2,ww=1;ww<=w;ww++)swap(f[t1=f[t1][0]][1],f[t2=f[t2][0]][1]);for(hh=1;hh<=h;hh++)swap(f[t1=f[t1][1]][0],f[t2=f[t2][1]][0]);for(t1=p1,t2=p2,hh=1;hh<=h;hh++)swap(f[t1=f[t1][1]][0],f[t2=f[t2][1]][0]);for(ww=1;ww<=w;ww++)swap(f[t1=f[t1][0]][1],f[t2=f[t2][0]][1]);}for(int i=1,p=lab[0][0];i<=n;i++){for(int j=1,t=p=f[p][1];j<=m;j++)cout<<v[t=f[t][0]]<<" ";cout<<'\n';}return 0;}

 
原创粉丝点击