zoukankan      html  css  js  c++  java
  • NOIp2018集训test-9-23

    这个NOI模拟题怕是比你们的NOIp模拟题要简单哦。。

    友好的生物

    应该是一道简单题,但是机房只有辉神一个人想到正解似乎。

    被我kd-tree水过去了(这不是kd-tree的裸题吗???(不是))

      1 //Achen
      2 #include<bits/stdc++.h>
      3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
      4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
      5 #define Formylove return 0
      6 #define inf 1e18
      7 const int N=100007;
      8 using namespace std;
      9 typedef long long LL;
     10 typedef double db;
     11 int n,K,D;
     12 LL C[10],ans;
     13 
     14 template<typename T>void read(T &x) {
     15     T f=1; x=0; char ch=getchar();
     16     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     17     if(ch=='-') f=-1,ch=getchar();
     18     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     19 }
     20 
     21 struct node {
     22     int d[5];
     23     friend bool operator <(const node&A,const node&B) {
     24         return A.d[D]<B.d[D];
     25     }
     26 }p[N],q[N],T;
     27 
     28 void get_min(int &x,int y) { if(x>y) x=y; }
     29 void get_max(int &x,int y) { if(x<y) x=y; }
     30 
     31 int rt,ch[N][2],dt[N][5][2];
     32 #define lc ch[x][0]
     33 #define rc ch[x][1]
     34 #define mid ((l+r)>>1)
     35 void update(int x,int l,int r) {
     36     For(i,0,K-1) dt[x][i][0]=dt[x][i][1]=p[x].d[i];
     37     if(lc) For(i,0,K-1) {
     38         get_min(dt[x][i][0],dt[lc][i][0]);
     39         get_max(dt[x][i][1],dt[lc][i][1]);
     40     }
     41     if(rc) For(i,0,K-1) {
     42         get_min(dt[x][i][0],dt[rc][i][0]);
     43         get_max(dt[x][i][1],dt[rc][i][1]);
     44     }
     45 }
     46 
     47 int build(int l,int r,int k) {
     48     if(l>r) return 0;
     49     D=k;
     50     sort(p+l,p+r+1);
     51     int x=((l+r)>>1);
     52     lc=build(l,x-1,(k+1)%K);
     53     rc=build(x+1,r,(k+1)%K);
     54     update(x,l,r);
     55     return x;
     56 }
     57 
     58 void get_ans(int x) {
     59     LL rs=0;
     60     For(i,0,K-2) rs+=abs(p[x].d[i]-T.d[i])*C[i];
     61     rs-=abs(p[x].d[K-1]-T.d[K-1])*C[K-1];
     62     ans=max(ans,rs);
     63 }
     64 
     65 LL guess_min(int x) {
     66     LL rs=0;
     67     For(i,0,K-2) {
     68         if(dt[x][i][0]<=T.d[i]&&dt[x][i][1]>=T.d[i]) continue;
     69         if(T.d[i]<dt[x][i][0]) rs+=(dt[x][i][0]-T.d[i])*C[i];
     70         else rs+=(T.d[i]-dt[x][i][1])*C[i];
     71     }
     72     rs-=max(abs(T.d[K-1]-dt[x][K-1][0]),abs(T.d[K-1]-dt[x][K-1][1]))*C[K-1];
     73     return rs;
     74 }
     75 
     76 LL guess_max(int x) {
     77     if(!x) return -inf;
     78     LL rs=0;
     79     For(i,0,K-2) {
     80         rs+=max(abs(T.d[i]-dt[x][i][0]),abs(T.d[i]-dt[x][i][1]))*C[i];
     81     }
     82     if(T.d[K-1]<dt[x][K-1][0]) rs-=(dt[x][K-1][0]-T.d[K-1])*C[K-1];
     83     else if(T.d[K-1]>dt[x][K-1][1]) rs-=(T.d[K-1]-dt[x][K-1][1])*C[K-1];
     84     return rs;
     85 }
     86 
     87 void qry(int x,int l,int r,int k) {
     88     if(!x||l>r) return ;
     89     get_ans(x);
     90     LL lg=guess_max(lc);
     91     LL rg=guess_max(rc);
     92     if(lg<=ans&&rg<=ans) return ;
     93     if(lg>=rg) {
     94         qry(lc,l,mid-1,(k+1)%K);
     95         if(rg>ans) qry(rc,mid+1,r,(k+1)%K);
     96     }
     97     else {
     98         qry(rc,mid+1,r,(k+1)%K);
     99         if(lg>ans) qry(lc,l,mid-1,(k+1)%K);
    100     }
    101 }
    102 
    103 #define ANS
    104 int main() {
    105 #ifdef ANS
    106     freopen("species.in","r",stdin);
    107     freopen("species.out","w",stdout);
    108 #endif
    109     read(n); read(K);
    110     For(i,0,K-1) read(C[i]);
    111     For(i,1,n) {
    112         For(j,0,K-1) read(p[i].d[j]);
    113         q[i]=p[i];
    114     }
    115     ans=-inf;
    116     rt=build(1,n,0);
    117     For(i,1,n) {
    118         T=q[i];
    119         qry(rt,1,n,0);
    120     }
    121     printf("%lld
    ",ans);
    122     //cerr<<clock()<<endl;
    123     Formylove;
    124 }
    kd-tree

    正解:

    这个题其实是三道题中最简单的一道。先来看这个问题的一个简化版,假设所有的属性都是差值越大越友好的话:

     

    那么,这个题目会变得简单很多,我们依次枚举在最有情况下,每一种属性值是编号小的动物大,还是编号大的动物大。假设,对于第i种属性,编号小的动物大这种情况用t[i]=-1表示,编号大的动物属性值大这种情况用t[i]=1表示。那么,动物i和动物j的属性值

     

    并且,我们总有一个时刻可以枚举对每一种属性的情况,使等号成立。所以,我们可以通过寻找右侧式子的最大值来确定左侧式子的最大值。

    回到本题,题目中的最后一个属性和前面的是反过来的,即差值越小越友好,在这种情况下,我们可以先将动物们按照最后一个属性值来排序,之后按照上面给出的做法实现就可以了。

    正解当然优美很多了

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 #define inf 1e18
     7 const int N=100007;
     8 using namespace std;
     9 typedef long long LL;
    10 typedef double db;
    11 int n,K,D;
    12 LL C[10],ans;
    13 
    14 template<typename T>void read(T &x) {
    15     T f=1; x=0; char ch=getchar();
    16     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    17     if(ch=='-') f=-1,ch=getchar();
    18     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    19 }
    20 
    21 struct node {
    22     int d[5];
    23     friend bool operator <(const node&A,const node&B) {
    24         return A.d[K-1]>B.d[K-1];
    25     }
    26 }p[N];
    27 
    28 #define ANS
    29 int main() {
    30 #ifdef ANS
    31     freopen("species.in","r",stdin);
    32     freopen("species.out","w",stdout);
    33 #endif
    34     read(n); read(K);
    35     For(i,0,K-1) read(C[i]);
    36     For(i,1,n) {
    37         For(j,0,K-1) read(p[i].d[j]);
    38     }
    39     sort(p+1,p+n+1);
    40     LL pr=inf;
    41     ans=-inf;
    42     int up=(1<<K-1)-1;
    43     For(t,0,up) {
    44         pr=inf;
    45         For(i,1,n) {
    46             LL tp=0;
    47             For(d,1,K-1) if(t&(1<<d-1)) tp-=C[d-1]*p[i].d[d-1];
    48             else tp+=C[d-1]*p[i].d[d-1]; 
    49             ans=max(ans,tp+C[K-1]*p[i].d[K-1]-pr);
    50             pr=min(pr,tp+C[K-1]*p[i].d[K-1]);
    51         }
    52     }
    53     printf("%lld
    ",ans);
    54     //cerr<<clock()<<endl;
    55     Formylove;
    56 }
    View Code

     

    基因重组

    这是个真水题,n^2dp随便怎么做,我做的时候脑子有点抽写得有点奇怪,还用了short卡空间。。但是这个dp随便怎么写都能过吧。

     1 //Achen
     2 #include<bits/stdc++.h>
     3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
     4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
     5 #define Formylove return 0
     6 const int N=5007;
     7 using namespace std;
     8 typedef long long LL;
     9 typedef double db;
    10 int n,m,up=24400,c1,c2,c3;
    11 short s1[N][N],f[N][N],mi[N],ans;
    12 LL x;
    13 char a[N],b[N],a2[N];
    14 
    15 template<typename T>void read(T &x) {
    16     T f=1; x=0; char ch=getchar();
    17     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    18     if(ch=='-') f=-1,ch=getchar();
    19     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    20 }
    21 
    22 void get_min(short &x,int y) { if(x>y) x=y; }
    23 
    24 #define ANS
    25 int main() {
    26 #ifdef ANS
    27     freopen("DNA.in","r",stdin);
    28     freopen("DNA.out","w",stdout);
    29 #endif
    30     read(x); if(x>up) c1=up+1; else c1=x;
    31     read(x); if(x>up) c2=up+1; else c2=x;
    32     read(x); if(x>up) c3=up+1; else c3=x;
    33     scanf("%s",a); n=strlen(a);
    34     For(i,0,n-1) {
    35         if(a[i]=='A') a2[i]='T';
    36         else if(a[i]=='T') a2[i]='A';
    37         else if(a[i]=='C') a2[i]='G';
    38         else if(a[i]=='G') a2[i]='C';
    39     }
    40     scanf("%s",b); m=strlen(b);
    41     Rep(i,n,1) Rep(j,m,1) {
    42         if(a[i-1]==b[j-1]) s1[i][j]=s1[i+1][j+1]+1;
    43         else s1[i][j]=0;
    44         if(a2[i-1]==b[j-1]) f[i][j]=f[i+1][j+1]+1;
    45         else f[i][j]=0;
    46     }
    47     For(i,1,n) For(j,1,m) s1[i][j]=max(s1[i][j],f[i][j]);
    48     memset(f,127,sizeof(f));
    49     memset(mi,127,sizeof(mi));
    50     mi[0]=0;
    51     f[0][0]=0; ans=up;
    52     For(i,0,n) {
    53         For(j,0,m) {
    54             get_min(f[i][j],(int)mi[j]+c2);
    55             mi[j]=min(mi[j],f[i][j]);
    56             int t=s1[i+1][j+1];
    57             get_min(f[i+t][j+t],(int)f[i][j]+c1);
    58             if(j==m) get_min(ans,(int)f[i][j]);
    59             else get_min(f[i][j+1],(int)f[i][j]+c3);
    60         }
    61     }
    62     printf("%d
    ",(int)ans);
    63     //cerr<<clock()<<endl;
    64     Formylove;
    65 }
    View Code

    危险的迷宫

    好多人切这题啊。。。全机房就我一个人不知道这题是费用流???

    这不是一道插头dp的裸题吗????

    人类,你们对插头dp一无所知!

    作死写了百行转移,结果大样例都没过,交上去还水过了50pt.

    然后de了一晚上。。。

    一个是有个地方n和m写反了,另外两个是两段轮廓线上一个是1一个是2的时候,如果这个格子本身是1或者2那么是不合法的,不能直接合并清0了!两句话价值一晚上+50pt。

      1 //Achen
      2 #include<bits/stdc++.h>
      3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
      4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
      5 #define Formylove return 0
      6 const int N=177148;
      7 using namespace std;
      8 typedef long long LL;
      9 typedef double db;
     10 int n,m,K,C,f[12][12][N],inf,pr[30];
     11 int a[15][15],is[15][15],rr[15][15],dn[15][15];
     12 
     13 template<typename T>void read(T &x) {
     14     T f=1; x=0; char ch=getchar();
     15     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
     16     if(ch=='-') f=-1,ch=getchar();
     17     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
     18 }
     19 
     20 void GM(int &x,int y) { if(x>y) x=y; }
     21 int get(int s,int k) {
     22     return s/pr[k-1]%3;
     23 }
     24 
     25 #define ANS
     26 int main() {
     27 #ifdef ANS
     28     freopen("maze.in","r",stdin);
     29     freopen("maze.out","w",stdout);
     30 #endif
     31     read(n); read(m);
     32     For(i,1,n) For(j,1,m) read(a[i][j]);
     33     read(K);
     34     For(i,1,K) {
     35         int x1,y1,x2,y2;
     36         read(x1); read(y1);
     37         read(x2); read(y2);
     38         if(x1>x2) swap(x1,x2),swap(y1,y2);
     39         if(x1<x2) dn[x1][y1]=1;
     40         else {
     41             if(y1>y2) swap(y1,y2);
     42             rr[x1][y1]=1;
     43         } 
     44     }
     45     read(C);
     46     For(i,1,C) {
     47         int x,y;
     48         read(x); read(y);
     49         is[x][y]=1;
     50     }
     51     For(i,1,C) {
     52         int x,y;
     53         read(x); read(y);
     54         is[x][y]=2;
     55     }
     56     /*For(i,1,n) {
     57         For(j,1,m) {
     58             printf("%d ",rr[i][j]);
     59         } puts("");
     60     }
     61     For(i,1,n) {
     62         For(j,1,m) {
     63             printf("%d ",dn[i][j]);
     64         } puts("");
     65     }
     66     For(i,1,n) {
     67         For(j,1,m) {
     68             if(is[i][j]) printf("%d(%d)",a[i][j],is[i][j]);
     69             else printf("%d",a[i][j]);
     70     }*/
     71     pr[0]=1;
     72     For(i,1,20) pr[i]=pr[i-1]*3;
     73     memset(f,127/3,sizeof(f));
     74     inf=f[0][0][0];
     75     f[1][1][0]=0;
     76     int up=pr[m+1]-1;
     77     For(i,1,n) {
     78         For(j,1,m) {
     79             For(s,0,up) if(f[i][j][s]!=inf) {
     80                 int prs=s;
     81                 if(j==1) s*=3;
     82                 int f1=get(s,j),f2=get(s,j+1);
     83                 int ii,jj;
     84                 if(j==m) ii=i+1,jj=1;
     85                 else ii=i,jj=j+1;
     86                 if(!f1) {
     87                     if(!f2) {
     88                         if(is[i][j]) {
     89                             if(rr[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j]],f[i][j][prs]+a[i][j]);
     90                             if(dn[i][j]) GM(f[ii][jj][s+is[i][j]*pr[j-1]],f[i][j][prs]+a[i][j]);
     91                         }
     92                         else {
     93                             GM(f[ii][jj][s],f[i][j][prs]);
     94                             if(rr[i][j]&&dn[i][j]) {
     95                                 GM(f[ii][jj][s+pr[j-1]+2*pr[j]],f[i][j][prs]+a[i][j]);
     96                                 GM(f[ii][jj][s+2*pr[j-1]+pr[j]],f[i][j][prs]+a[i][j]);
     97                             }
     98                         }
     99                     }
    100                     if(f2==1) {
    101                         if(is[i][j]==2) 
    102                             GM(f[ii][jj][s-pr[j]],f[i][j][prs]+a[i][j]);
    103                         else if(!is[i][j]) {
    104                             if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
    105                             if(dn[i][j]) GM(f[ii][jj][s+pr[j-1]-pr[j]],f[i][j][prs]+a[i][j]);
    106                         }
    107                     }
    108                     if(f2==2) {
    109                         if(is[i][j]==1) 
    110                             GM(f[ii][jj][s-2*pr[j]],f[i][j][prs]+a[i][j]);
    111                         else if(!is[i][j]) {
    112                             if(rr[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
    113                             if(dn[i][j]) GM(f[ii][jj][s+2*pr[j-1]-2*pr[j]],f[i][j][prs]+a[i][j]);
    114                         }
    115                     }
    116                 }
    117                 else if(f1==1) {
    118                     if(!f2) {
    119                         if(is[i][j]==2) 
    120                             GM(f[ii][jj][s-pr[j-1]],f[i][j][prs]+a[i][j]);
    121                         else if(!is[i][j]) {
    122                             if(rr[i][j]) GM(f[ii][jj][s-pr[j-1]+pr[j]],f[i][j][prs]+a[i][j]);
    123                             if(dn[i][j]) GM(f[ii][jj][s],f[i][j][prs]+a[i][j]);
    124                         }
    125                     }
    126                     if(f2==1) ;
    127                     if(f2==2&&!is[i][j]) 
    128                         GM(f[ii][jj][s-pr[j-1]-2*pr[j]],f[i][j][prs]+a[i][j]);
    129                 }
    130                 else if(f1==2) {
    131                     if(!f2) {
    132                         if(is[i][j]==1) 
    133                             GM(f[ii][jj][s-2*pr[j-1]],f[i][j][s]+a[i][j]);
    134                         else if(!is[i][j]) {
    135                             if(rr[i][j]) GM(f[ii][jj][s-2*pr[j-1]+2*pr[j]],f[i][j][s]+a[i][j]);
    136                             if(dn[i][j]) GM(f[ii][jj][s],f[i][j][s]+a[i][j]);
    137                         }
    138                     }
    139                     if(f2==1&&!is[i][j]) 
    140                         GM(f[ii][jj][s-2*pr[j-1]-pr[j]],f[i][j][s]+a[i][j]);
    141                     if(f2==2) ;
    142                 }
    143                 s=prs;
    144                 if(f[3][4][0]!=inf) {
    145                     int debug=1;
    146                 }
    147             }
    148         }        
    149     }
    150     if(f[n+1][1][0]==inf) puts("-1");
    151     else printf("%d
    ",f[n+1][1][0]);
    152     //cerr<<clock()<<endl;
    153     Formylove;
    154 }
    View Code
  • 相关阅读:
    第十周课程总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告(六)
    第七周课程总结&实验报告(五)
    第六周&java实验报告四
    第五周课程总结&试验报告(三)
    课程总结
    第十四周课程总结
    第十三周学习总结
    第十二周编程总结
  • 原文地址:https://www.cnblogs.com/Achenchen/p/9745528.html
Copyright © 2011-2022 走看看