zoukankan      html  css  js  c++  java
  • 2009 Multi-University Training Contest 4

    跟着训练赛做的,每道题都学到很多,这次的数据都比较好心,输入简单,思路容易想,但是代码都有点蛋疼

    1. hdu2845 Beans 二次DP
      /*
      ID: neverchanje
      PROG:
      LANG: C++11
      */
      #include<vector>
      #include<iostream>
      #include<cstring>
      #include<string>
      #include<algorithm>
      #include<cmath>
      #include<cstdio>
      #include<set>
      #include<queue>
      #include<map>
      using namespace std;
      
      int n,m,t;
      int dp[200000],p[200000];
       
      int main(){
      //    freopen(".in","r",stdin);
      //    freopen(".out","w",stdout);
          while(cin>>m>>n){
              memset(dp,0,sizeof(dp));
              for(int i=1;i<=m;i++){
                  dp[0]=0;
                  scanf("%d",&dp[1]);
                  for(int j=2;j<=n;j++)
                  {
                      scanf("%d",&t);
                      dp[j] = max( dp[j-2]+t , dp[j-1] );
                  }
                  p[i]=dp[n];
              }
              
              memset(dp,0,sizeof(dp));
              dp[1]=p[1];
              for(int i=2;i<=m;i++){
                  dp[i] = max( dp[i-2]+p[i] , dp[i-1] );
              }
              cout<<dp[m]<<endl;
          }
          return 0;
      }
      
      /*
      DESCRIPTION:
      如果只有一行的话,最大不连续子序列和为 
      dp[i][0] = max(dp[j][1]) (j<i) 
      dp[i][1] = dp[i-1][0] + a[i] dp[i]为以i结尾的子序列和
      但是这样有On^2 
      
      如果是以dp[i]表示在i之前的最大不连续子序列和的话
      dp[i] = max( dp[i-2] + a[i] , dp[i-1] )
      */
      View Code
    2. hdu2846 Repository Trie树变形
      /*
      ID: neverchanje
      PROG:
      LANG: C++11
      */
      #include<vector>
      #include<iostream>
      #include<cstring>
      #include<string>
      #include<algorithm>
      #include<cmath>
      #include<cstdio>
      #include<set>
      #include<queue>
      #include<map>
      using namespace std;
      
      int n,q;
      char s[21];
      struct node{
          node* ch[26];
          int val;
          int id;
          node(){
              for(int i=0;i<26;i++)
                  ch[i]=NULL;
              val=0;
              id=-1;
          }
      };
      node root;
      
      int idx(char& x){
          return x-'a';
      }
      
      void insert(char* s,int id){
          int len=strlen(s),t;
          node* p=&root;
          for(int i=0;i<len;i++){
              t=idx(s[i]);
              if(p->ch[t]==NULL)
                  p->ch[t]=new node;    
              p=p->ch[t];
              if(p->id==id)
                  continue;
              (p->val)++;///////////////
              p->id=id;
          }
      }
      
      int query(char* s){
          int len=strlen(s),t;
          node* p=&root;
          for(int i=0;i<len;i++){
              t=idx(s[i]);
              if(p->ch[t]==NULL)
                  return 0;
              p=p->ch[t];
          }
          return p->val;
      }
      
      int main(){
      //    freopen(".in","r",stdin);
      //    freopen(".out","w",stdout);
      
          cin>>n;
          getchar();
          for(int i=0;i<n;i++){
              gets(s);
              int len=strlen(s);
              for(int j=0;j<len;j++)
                  insert(s+j,i);
          }
          
          cin>>q;getchar();
          for(int i=0;i<q;i++)
          {
              gets(s);
              printf("%d
      ",query(s));
          }
          return 0;
      }
      
      /*
      DESCRIPTION:
      每一个字符串都要被分解成子串,然后存到trie树中,但是这样会出现重复的情况,同一个字符串中的子串在trie树上的节点需要绑定一个id,如果id相同,则计数不能加1
      可画图理解 
      */
      View Code
    3. hdu2847 Binary String 暴力枚举+lcs
      /*
      ID: neverchanje
      PROG:
      LANG: C++11
      */
      #include<vector>
      #include<iostream>
      #include<cstring>
      #include<string>
      #include<algorithm>
      #include<cmath>
      #include<cstdio>
      #include<set>
      #include<queue>
      #include<map>
      using namespace std;
      
      char s[30];
      int k,bin,la,lb;
      int a[30];//保存原串 
      int b[30];//保存改动后的串 
      int m;//倍数 
      int nz,no; 
      int nzz,noo;//先比较0和1的个数来剪枝 
      int dp[30][30];
      
      int lcs(int* a,int* b,int la,int lb){
          memset(dp,0,sizeof(dp));
          for(int i=1;i<=la;i++){
              for(int j=1;j<=lb;j++){
                  if(a[i]==b[j])
                      dp[i][j] = dp[i-1][j-1]+1;
                  else
                      dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
              }
          }
          return dp[la][lb];
      }
      
      int main(){
      //    freopen(".in","r",stdin);
      //    freopen(".out","w",stdout);
          while(scanf("%s%d",s,&k)!=EOF){
              la = strlen(s);
              nz=no=0;
              memset(a,0,sizeof(a));
              memset(b,0,sizeof(b));
              
              for(int i=1;i<=la;i++){
                  a[i]=s[i-1]-'0';
                  if(a[i]==0)
                      nz++;
                  else no++;
              }
              
              bin=0;
              for(int i=la-1;i>=0;i--){//化成十进制
                  bin+=a[la-i]*(1<<i);
              }
              if(bin==0)
              {
                  cout<<0<<endl;
                  continue;
              }
              m=bin/k;
              if(m*k!=bin)
                  ++m;
              while(1){
                  bin=m*k;
                  nzz=noo=lb=0;
                  
                  for(int i=1;bin>0;i++)//逆序存储 
                  {
                      b[i]=bin&1;
                      bin=bin>>1;
                      lb++;
                      if(b[i]==0)
                          nzz++;
                      else
                          noo++;
                  }
                  if(nzz<nz || noo<no){
                      m++;continue;
                  }
                  
                  int l=1,r=lb,t;
                  while(l<r){//因为a是顺序的,也要把b转成顺序 
                      t=b[l];b[l]=b[r];b[r]=t;
                      l++;r--;
                  }
              //    for(int i=1;i<=lb;i++)    cout<<b[i];
                  if(lcs(a,b,la,lb)!=la)
                  {
                      m++;
                      continue; 
                  }
                  else
                  {
                      for(int i=1;i<=lb;i++)    printf("%d",b[i]);
                      printf("
      ");
                      break;
                  }
              }    
          }
          return 0;
      }
      
      /*
      DESCRIPTION:
      暴力:
      对于二进制数bin,要想整除k,可以暴力枚举k的倍数。判断bin能否达到 
      只是还要有限制条件: 
      bin的1和0的数目不能比原来少,即使1和0的数目一样了,相对位置也不能变
      所以要用到lcs,如果lcs最开始的二进制长度 则继续 
      
      注意:
      若bin==0    则答案为0 
      */
      View Code
    4. hdu2848 Number Cutting Game 博弈DFS (这题太难打了,细节各种错)
      /*
      ID: neverchanje
      PROG:
      LANG: C++11
      */
      #include<vector>
      #include<iostream>
      #include<cstring>
      #include<string>
      #include<algorithm>
      #include<cmath>
      #include<cstdio>
      #include<set>
      #include<queue>
      #include<map>
      using namespace std;
      
      long long n;//大数居然用long long.....fuck
      int k;
      long long deci[23];
      
      int solve();
      
      int length(long long x){
          int len=0;
          while(x){
              len++;
              x/=10;
          }
          return len;
      }
      
      void dfs(long long nn,long long res,int kk, int& yes){ //对一个数进行拆分操作 
          
      //    printf("%d %d %d %d 
      " ,nn,res,kk,yes);
          if(yes) return; 
          int len=length(nn);
          if(len<kk){
              yes=0;
              return;
          }
          if(kk==1){
              res+=nn;
              n=res;
              if(!solve())
              {
                  yes=1;
                  return;
              }
          }
          for(int i=len-1;i>=1;i--){
          //    cout<<"break
      ";
              dfs(nn/deci[i],res+nn%deci[i],kk-1,yes);
              if(yes)        return;
          }
      }
      
      int solve(){ //判断这个数能不能让使用这个操作的一方赢 
          int len=length(n);
          if(len<k)    return 0;
          if(len-k+2<k)    return 1;
          long long nn=n;
          int yes=0;
          dfs(nn,0,k,yes);
          return yes;
      }
       
      int main(){
          
          deci[0]=1;
          for(int i=1;i<=20;i++)
              deci[i]=deci[i-1]*10;
              
          while(cin>>n>>k)
          {    
              cout<<solve()<<endl;
          }
          return 0;
      }
      
      /*
      DESCRIPTION:
      length(n)<k,则输
      length(n)==k 能保证必赢 9|9|9 3        9|9 2
      length(n)==k+1 不能保证必赢,也不能保证必输 9|9|99 3     99|9 2
      用k把一个数分解出最大数时,如果先分解出k-1位,后面都分解成1位,这样保证加起来最大,而这个最大数最多只有length(n)-k+2位
      9|999 2 
      9|9|9999 3    9|9|999 3  
      9|9|9|9999 4
      如果length(n)-k+2<k 对手输,这种方案必赢,所以一定会取,length(n)==k的方案也包含在里面 
      
      */
      View Code
    5. 这题没看懂,以后回来做
  • 相关阅读:
    Taro api封装
    taro中如何定义全局变量
    移动端悬浮框可移动,可回弹,Vue and React
    VS2015 安装mvc4安装包以及vs2010 sp1后导致Razor语法失效代码不高亮(能正常运行)/视图页面无法智能提示(.cshtml)解决办法
    C#6.0新特性的尝试
    Visual Studio Code 添加设置代码段(snippet)
    AngularJs的$http发送POST请求,php无法接收Post的数据解决方案
    [Asp.net mvc] 在Asp.net mvc 中使用MiniProfiler
    [Asp.net mvc]实体更新异常:存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。
    win8.1右键新建菜单添加新建php文件
  • 原文地址:https://www.cnblogs.com/neverchanje/p/3638543.html
Copyright © 2011-2022 走看看