zoukankan      html  css  js  c++  java
  • uoj123 【NOI2013】小Q的修炼

    搞了一下午+半晚上。其实不是很难。

    提答题重要的是要发现数据的特殊性质,然后根据不同数据写出不同的算法获得其对应的分数。

    首先前两个测试点我们发现可以直接暴搜通过,事实上对于每个数据都暴搜加上一定的次数限制,都可以获得两分的好成绩。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 int n,m,a[105],ans=-0x7fffffff;
     8 int fin[1000500],st[1000500];
     9 struct num{
    10     int x1,x2;
    11     num(){x1=x2=0;}
    12     num(int x,char o){
    13         if(o=='v')x1=x,x2=0;
    14         else x1=0,x2=x;
    15     }
    16 };
    17 struct data{
    18     char o,f;
    19     num x,y;
    20     int s1,s2;
    21 }d[100500];
    22 char getc(){
    23     char ch=getchar();
    24     while(ch!='v'&&ch!='c'&&ch!='i'&&ch!='s'&&ch!='+'&&ch!='-')
    25         ch=getchar();
    26     return ch;
    27 }
    28 void dfs(int x,int step){
    29     if(x>n||x<1){
    30         if(a[1]>ans){
    31             for(int i=1;i<step;i++)
    32                 fin[i]=st[i];
    33             ans=a[1];
    34         }
    35         return ;
    36     }
    37     if(d[x].o=='v'){
    38         int now=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
    39         if(d[x].f=='+')a[d[x].x.x1]+=now;
    40         else a[d[x].x.x1]-=now;
    41         dfs(x+1,step);
    42         if(d[x].f=='+')a[d[x].x.x1]-=now;
    43         else a[d[x].x.x1]+=now;
    44     }
    45     if(d[x].o=='i'){
    46         int x1=d[x].x.x1?a[d[x].x.x1]:d[x].x.x2;
    47         int x2=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
    48         if(x1<x2)dfs(d[x].s1,step);
    49         else dfs(d[x].s2,step);
    50     }
    51     if(d[x].o=='s'){
    52         st[step]=1,dfs(d[x].s1,step+1);
    53         st[step]=2,dfs(d[x].s2,step+1);
    54     }
    55 }
    56 int read(){
    57     int a=0,f=1;char ch=getchar();
    58     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    59     while(ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
    60     return a*f;
    61 }
    62 int main(){
    63 freopen("train1.in","r",stdin);
    64 freopen("train1.in","r",stdin);
    65     scanf("%d%d",&n,&m);
    66     for(int i=1;i<=n;i++){
    67         d[i].o=getc();
    68         if(d[i].o=='v'){
    69             d[i].x=num(read(),'v');
    70             d[i].f=getc();
    71             d[i].y=num(read(),getc());
    72         }
    73         else if(d[i].o=='s'){
    74             d[i].s1=read();
    75             d[i].s2=read();
    76         }
    77         else if(d[i].o=='i'){
    78             d[i].x=num(read(),getc());
    79             d[i].y=num(read(),getc());
    80             d[i].s1=read();
    81             d[i].s2=read();
    82         }
    83     }
    84     dfs(1,1);
    85     for(int i=1;fin[i];i++)
    86         printf("%d
    ",fin[i]);
    87     return 0;
    88 }
    View Code

    对于第三个测试点,我们可以发现这其实是分成了好多独立的块,长度是170,我们发现,在块内有不多的决策点,然后块的末尾会将所有变量都加给1,然后清零,所以我们可以每个块内暴搜,然后合并起来。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 int n,m,a[105],ans=-0x7fffffff;
     8 int fin[1000500],st[1000500];
     9 struct num{
    10     int x1,x2;
    11     num(){x1=x2=0;}
    12     num(int x,char o){
    13         if(o=='v')x1=x,x2=0;
    14         else x1=0,x2=x;
    15     }
    16 };
    17 struct data{
    18     char o,f;
    19     num x,y;
    20     int s1,s2;
    21 }d[100500];
    22 char getc(){
    23     char ch=getchar();
    24     while(ch!='v'&&ch!='c'&&ch!='i'&&ch!='s'&&ch!='+'&&ch!='-')
    25         ch=getchar();
    26     return ch;
    27 }
    28 void dfs(int x,int step,int pos){
    29     if(x>(pos*170)||x<=(pos-1)*170){
    30         if(a[1]>ans){
    31             for(int i=1;i<step;i++)
    32                 fin[i]=st[i];
    33             ans=a[1];
    34         }
    35         return ;
    36     }
    37     if(d[x].o=='v'){
    38         int now=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
    39         if(d[x].f=='+')a[d[x].x.x1]+=now;
    40         else a[d[x].x.x1]-=now;
    41         dfs(x+1,step,pos);
    42         if(d[x].f=='+')a[d[x].x.x1]-=now;
    43         else a[d[x].x.x1]+=now;
    44     }
    45     if(d[x].o=='i'){
    46         int x1=d[x].x.x1?a[d[x].x.x1]:d[x].x.x2;
    47         int x2=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
    48         if(x1<x2)dfs(d[x].s1,step,pos);
    49         else dfs(d[x].s2,step,pos);
    50     }
    51     if(d[x].o=='s'){
    52         st[step]=1,dfs(d[x].s1,step+1,pos);
    53         st[step]=2,dfs(d[x].s2,step+1,pos);
    54     }
    55 }
    56 int read(){
    57     int a=0,f=1;char ch=getchar();
    58     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    59     while(ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
    60     return a*f;
    61 }
    62 int main(){
    63 freopen("train3.in","r",stdin);
    64 freopen("train3.out","w",stdout);
    65     scanf("%d%d",&n,&m);
    66     for(int i=1;i<=n;i++){
    67         d[i].o=getc();
    68         if(d[i].o=='v'){
    69             d[i].x=num(read(),'v');
    70             d[i].f=getc();
    71             d[i].y=num(read(),getc());
    72         }
    73         else if(d[i].o=='s'){
    74             d[i].s1=read();
    75             d[i].s2=read();
    76         }
    77         else if(d[i].o=='i'){
    78             d[i].x=num(read(),getc());
    79             d[i].y=num(read(),getc());
    80             d[i].s1=read();
    81             d[i].s2=read();
    82         }
    83     }
    84     for(int i=1;i<=200;i++){
    85         ans=-0x7fffffff;
    86         memset(fin,0,sizeof fin);
    87         memset(a,0,sizeof a);
    88         dfs((i-1)*170+1,1,i);
    89         for(int i=1;fin[i];i++)
    90             printf("%d
    ",fin[i]);
    91     }
    92     return 0;
    93 }
    View Code

    对于456个测试点,我们发现只有两个变量,相当于是用钱买成就,于是我们可以做一个简单的dp,注意56两个点不一定跳到后面相邻的那个,所以又多了不少细节。我的f[i][j]表示在i处买完剩了j元钱的答案,g表示不在这里买。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <vector>
      7 using namespace std;
      8 int n,m,a[105],ans=-0x7fffffff;
      9 int fin[1000500],st[1000500];
     10 struct num{
     11     int x1,x2;
     12     num(){x1=x2=0;}
     13     num(int x,char o){
     14         if(o=='v')x1=x,x2=0;
     15         else x1=0,x2=x;
     16     }
     17 };
     18 struct data{
     19     char o,f;
     20     num x,y;
     21     int s1,s2,id;
     22 }d[100500];
     23 char getc(){
     24     char ch=getchar();
     25     while(ch!='v'&&ch!='c'&&ch!='i'&&ch!='s'&&ch!='+'&&ch!='-')
     26         ch=getchar();
     27     return ch;
     28 }
     29 int read(){
     30     int a=0,f=1;char ch=getchar();
     31     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     32     while(ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
     33     return a*f;
     34 }
     35 int f[2050][10050],g[2050][10050],pp[2050];
     36 int c[2050],w[2050],tot,pf[2050][10050],pg[2050][10050];
     37 vector<int> pr[2050];
     38 void dfs(int x,int y,int o){
     39     if(!x)return ;
     40     if(o==1||y>=c[x])fin[x]=o;
     41     else fin[x]=0;
     42     if(o==1){
     43         if(pf[x][y])dfs(pf[x][y],y+c[x],2);
     44         else dfs(x-1,y+c[x],1);
     45     }
     46     else{
     47         if(pg[x][y])dfs(pg[x][y],y,2);
     48         else dfs(x-1,y,1);
     49     }
     50 }
     51 int main(){
     52 freopen("train6.in","r",stdin);
     53 freopen("train6.out","w",stdout);
     54     scanf("%d%d",&n,&m);
     55     for(int i=1;i<=n;i++){
     56         d[i].o=getc();
     57         if(d[i].o=='v'){
     58             d[i].x=num(read(),'v');
     59             d[i].f=getc();
     60             d[i].y=num(read(),getc());
     61             if(i==1){d[i].id=0;continue;}
     62             if(d[i].x.x1==2)c[++tot]=d[i].y.x2;
     63             else w[tot]=d[i].y.x2;
     64             d[i].id=tot;
     65         }
     66         else if(d[i].o=='s'){
     67             pp[tot+1]=i;
     68             d[i].id=tot+1;
     69             d[i].s1=read();
     70             d[i].s2=read();
     71         }
     72         else if(d[i].o=='i'){
     73             d[i].id=tot+1;
     74             d[i].x=num(read(),getc());
     75             d[i].y=num(read(),getc());
     76             d[i].s1=read();
     77             d[i].s2=read();
     78         }
     79     }
     80     d[12002].id=tot+1;
     81     for(int i=1;i<=tot;i++)
     82         pr[d[d[pp[i]].s2].id].push_back(i);
     83     memset(f,-0x3f,sizeof f);
     84     f[0][10000]=0;
     85     int p1,p2;
     86     for(int i=1;i<=tot;i++){
     87         for(int j=c[i];j<=10000;j++){
     88             f[i][j-c[i]]=f[i-1][j]+w[i];
     89             pf[i][j-c[i]]=0;
     90             for(int k=0;k<pr[i].size();k++)if(g[pr[i][k]][j]+w[i]>f[i][j-c[i]]){
     91                 f[i][j-c[i]]=g[pr[i][k]][j]+w[i];
     92                 pf[i][j-c[i]]=pr[i][k];
     93             }
     94             if(f[i][j-c[i]]>ans){
     95                 ans=f[i][j-c[i]];
     96                 p1=i;p2=j-c[i];
     97             }
     98         }
     99         for(int j=0;j<=10000;j++){
    100             g[i][j]=f[i-1][j];
    101             pg[i][j]=0;
    102             for(int k=0;k<pr[i].size();k++)if(g[pr[i][k]][j]>g[i][j]){
    103                 g[i][j]=g[pr[i][k]][j];
    104                 pg[i][j]=pr[i][k];
    105             }
    106         }
    107     }
    108     dfs(p1,p2,1);
    109     for(int i=1;i<=tot;i++)if(fin[i])printf("%d
    ",fin[i]);
    110     return 0;
    111 }
    View Code

    最后四个点我们发现明显就是暴搜和dp拼起来,我们对于每个块内搜出他的贡献,然后和上面一样dp就好了。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <vector>
      7 using namespace std;
      8 int n,m,a[105],ans=-0x7fffffff;
      9 int fin[2050][1050],st[1050];
     10 int f[2050][10050],g[2050][10050],pp[2050];
     11 int c[2050],w[2050],tot,pf[2050][10050],pg[2050][10050];
     12 vector<int> pr[2050];
     13 struct num{
     14     int x1,x2;
     15     num(){x1=x2=0;}
     16     num(int x,char o){
     17         if(o=='v')x1=x,x2=0;
     18         else x1=0,x2=x;
     19     }
     20 };
     21 struct data{
     22     char o,f;
     23     num x,y;
     24     int s1,s2,id;
     25 }d[100500];
     26 char getc(){
     27     char ch=getchar();
     28     while(ch!='v'&&ch!='c'&&ch!='i'&&ch!='s'&&ch!='+'&&ch!='-')
     29         ch=getchar();
     30     return ch;
     31 }
     32 int be,en;
     33 void dfs(int x,int step,int pos){
     34     if(x>en||x<be){
     35         if(a[1]>w[pos]){
     36             for(int i=1;i<step;i++)
     37                 fin[pos][i]=st[i];
     38             w[pos]=a[1];
     39         }
     40         return ;
     41     }
     42     if(d[x].o=='v'){
     43         int now=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
     44         if(d[x].f=='+')a[d[x].x.x1]+=now;
     45         else a[d[x].x.x1]-=now;
     46         dfs(x+1,step,pos);
     47         if(d[x].f=='+')a[d[x].x.x1]-=now;
     48         else a[d[x].x.x1]+=now;
     49     }
     50     if(d[x].o=='i'){
     51         int x1=d[x].x.x1?a[d[x].x.x1]:d[x].x.x2;
     52         int x2=d[x].y.x1?a[d[x].y.x1]:d[x].y.x2;
     53         if(x1<x2)dfs(d[x].s1,step,pos);
     54         else dfs(d[x].s2,step,pos);
     55     }
     56     if(d[x].o=='s'){
     57         st[step]=1,dfs(d[x].s1,step+1,pos);
     58         st[step]=2,dfs(d[x].s2,step+1,pos);
     59     }
     60 }
     61 int read(){
     62     int a=0,f=1;char ch=getchar();
     63     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     64     while(ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
     65     return a*f;
     66 }
     67 void dfs1(int x,int y,int o){
     68     if(!x)return ;
     69     if(o==1||y>=c[x])fin[x][0]=o;
     70     else fin[x][0]=0;
     71     if(o==1){
     72         if(pf[x][y])dfs1(pf[x][y],y+c[x],2);
     73         else dfs1(x-1,y+c[x],1);
     74     }
     75     else{
     76         if(pg[x][y])dfs1(pg[x][y],y,2);
     77         else dfs1(x-1,y,1);
     78     }
     79 }
     80 int main(){
     81 freopen("train10.in","r",stdin);
     82 freopen("train10.out","w",stdout);
     83     scanf("%d%d",&n,&m);
     84     memset(w,-0x3f,sizeof w);
     85     for(int i=1;i<=n;i++){
     86         d[i].o=getc();
     87         if(d[i].o=='v'){
     88             d[i].x=num(read(),'v');
     89             d[i].f=getc();
     90             d[i].y=num(read(),getc());
     91             if(i==1){d[i].id=0;continue;}
     92             if(d[i].x.x1==2){
     93                 c[tot]=d[i].y.x2;
     94                 be=i+1;
     95             }
     96             d[i].id=tot;
     97         }
     98         else if(d[i].o=='s'){
     99             d[i].s1=read();
    100             d[i].s2=read();
    101             d[i].id=tot;
    102             if(!pp[tot])pp[tot]=i;
    103         }
    104         else if(d[i].o=='i'){
    105             d[i].x=num(read(),getc());
    106             d[i].y=num(read(),getc());
    107             d[i].s1=read();
    108             d[i].s2=read();
    109             if(d[i].x.x1==2){
    110                 if(tot){en=i-1;dfs(be,1,tot);}
    111                 tot++;
    112                 for(int j=i-1;d[j].o=='i'&&d[j].s2==0;j--)
    113                     d[j].id=tot;
    114             }
    115             d[i].id=tot;
    116         }
    117     }
    118     en=n;
    119     dfs(be,1,tot);
    120     for(int i=1;i<=tot;i++)
    121         pr[d[d[pp[i]].s2].id].push_back(i);
    122     memset(f,-0x3f,sizeof f);
    123     f[0][1000]=0;
    124     int p1,p2;
    125     for(int i=1;i<=tot;i++){
    126         for(int j=c[i];j<=1000;j++){
    127             f[i][j-c[i]]=f[i-1][j]+w[i];
    128             pf[i][j-c[i]]=0;
    129             for(int k=0;k<pr[i].size();k++)if(g[pr[i][k]][j]+w[i]>f[i][j-c[i]]){
    130                 f[i][j-c[i]]=g[pr[i][k]][j]+w[i];
    131                 pf[i][j-c[i]]=pr[i][k];
    132             }
    133             if(f[i][j-c[i]]>ans){
    134                 ans=f[i][j-c[i]];
    135                 p1=i;p2=j-c[i];
    136             }
    137         }
    138         for(int j=0;j<=1000;j++){
    139             g[i][j]=f[i-1][j];
    140             pg[i][j]=0;
    141             for(int k=0;k<pr[i].size();k++)if(g[pr[i][k]][j]>g[i][j]){
    142                 g[i][j]=g[pr[i][k]][j];
    143                 pg[i][j]=pr[i][k];
    144             }
    145         }
    146     }
    147     dfs1(p1,p2,1);
    148     for(int i=1;i<=tot;i++)if(fin[i][0]){
    149         printf("%d
    ",fin[i][0]);
    150         if(fin[i][0]==1){
    151             for(int j=1;fin[i][j];j++)
    152                 printf("%d
    ",fin[i][j]);
    153         }
    154     }
    155     return 0;
    156 }
    View Code

    提答,提答。

  • 相关阅读:
    js修改input的type属性问题(兼容所有浏览器,主要用于密码类的默认有提示文字的效果)
    让一个div始终固定在页面的某一固定位置的方法
    js在IE8+兼容String没有trim方法,写一个兼容ie8一下的浏览器的trim()方法
    js用new Object创建json数据
    js+php实现文件上传显示文件上传进度条的插件
    关于一个页面的tab切换整体页面刷新而tab标签处是同一个文件怎么做焦点的问题
    B树及2-3树的python实现
    二叉查找树转变为有序双向链表
    Django中的静态文件管理
    Django文档——Model中的ForeignKey,ManyToManyField与OneToOneField
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/8982070.html
Copyright © 2011-2022 走看看