zoukankan      html  css  js  c++  java
  • 简单dp hdu-4105-Electric wave

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4105

    题目意思:

    给一个字符串,求最大的分隔空格数,记所有被分隔的数为a1,a2,a3,.....

    使得 a1<a2>a3<a4>a5.....

    解题思路:

    简单的dp;

    记dp[0][i][j]表示从第i个字符开始到结束,且以第i~j个字符组成的数作为谷值的最大的分隔的数。

    记dp[1][i][j]                          。。。                                                                   峰数....

    则dp[0][i][j]=max(dp[0][i][j],dp[1][j+1][k]+1) // 其中(j+1~k)组成的数的值大于(i~j)组成的数。

        dp[1][i][j]=max(dp[1][i][j],dp[0][j+1][k]+1) // 其中(j+1~k)组成的数的值小于(i~j)组成的数。

    注意:

    1、有前置0,比较的时候消除前置0.

    2、比较的时候用strcmp和strncpy超时,直接一位一位的比。

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #define eps 1e-6
    #define INF 0x1f1f1f1f
    #define PI acos(-1.0)
    #define ll __int64
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    /*
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    */
    
    int dp[2][110][110]; //dp[0][i][j]表示从第i个字符开始长度为j的作为低谷时能分隔的最多数的个数
    char save[110];
    char temp1[110],temp2[110];
    
    bool ismin(int i,int j,int k,int p)
    {
       while(save[i]=='0')
          i++;
       while(save[k]=='0')
          k++;
       if(k>p)
          return false;
       if(i>j)
          return true;
       if(j-i<p-k)
          return true;
       else if(j-i>p-k)
          return false;
       else
       {
          for(int pp=0;pp<=j-i;pp++)
             if(save[pp+i]<save[pp+k])
                return true;
             else if(save[pp+i]>save[pp+k])
                return false;
       }
       return false;
    }
    bool Ismin(char * a,char * b) //用这里的函数,居然超时
    {
       int len1=strlen(a),len2=strlen(b);
       int i=0,j=0;
    
       while(a[i]=='0')
          i++;
       while(a[j]=='0')
          j++;
       if(j>=len2)
          return false;
       if(i>=len1)
          return true;
       if(len1-i<len2-j)
          return true;
       else if(len1-i>len2-j)
          return false;
       else
       {
          if(strcmp(a+i,b+i)<0)
             return true;
          else
             return false;
       }
    }
    int main()
    {
       int n;
    
       while(~scanf("%d",&n))
       {
          memset(dp,0,sizeof(dp));
          scanf("%s",save+1);
          for(int i=1;i<=n;i++) //初始化
          {
             dp[0][i][n]=1;
             dp[1][i][n]=1;
          }
    
          for(int i=n-1;i>=1;i--) //计算 dp[][i][j]
          {
             for(int j=i;j<n;j++)
             {
                //strncpy(temp1,save+i,j-i+1);
               // temp1[j-i+1]='';
               int k=j+1;
                for(int p=k;p<=n;p++)
                {
                   //strncpy(temp2,save+k,p-k+1);
                   //temp2[p-k+1]='';
                  // printf("2:%s
    ",temp2);
                   if(ismin(k,p,i,j)) //后面的小,说明当前可以作为峰值
                      dp[1][i][j]=max(dp[1][i][j],dp[0][k][p]+1);
                   else if(ismin(i,j,k,p)) //后面的大,说明当前可以作为谷值
                      dp[0][i][j]=max(dp[0][i][j],dp[1][k][p]+1);
                }
                //printf("i:%d j:%d %d %d
    ",i,j,dp[0][i][j],dp[1][i][j]);
             }
          }
          int ans=0; //找到分隔多的数的个数
          for(int i=1;i<=n;i++)
             ans=max(ans,dp[0][1][i]);
          printf("%d
    ",ans-1); //隔板为分隔的数个数-1
    
       }
       return 0;
    }
    
    


  • 相关阅读:
    在.wxml文件中使用方法
    Element日期区间选择器限制选择范围
    规定段落中的文本不进行换行
    文件大小换算
    elementUI的message消息提示改成只能同时存在一个
    SQL 执行顺序
    SQL Left join
    wpf datagrid 行双击事件
    关于Infragistics.WebUI.UltraWebGrid的使用
    ASP.NET 根据汉字获取汉字拼音的首字母(含多音字)
  • 原文地址:https://www.cnblogs.com/riskyer/p/3241419.html
Copyright © 2011-2022 走看看