zoukankan      html  css  js  c++  java
  • POJ 13295 最佳加法表达式 【dp】【北大ACM/ICPC竞赛训练】

    高精度写了半天

    dp[i][j]代表前i个数字放j个加号的最小值。转移的时候枚举在第k个数字后放加号,那么k最大在i-1后放加号,最小在第j个数后面放加号。

    O(i^2 * j)复杂度

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 struct bigN{
     6     int a[55],length;//从低位到高位 
     7     bigN(int num[],int len){//num是从高位到低位
     8         memset(a,0,sizeof(a));
     9         length = len;
    10         for(int i=0;i<len;i++) a[i]=num[len-i-1];    
    11     }
    12     bigN(){
    13         length=0;
    14         memset(a,0,sizeof(a));
    15     }
    16     bigN operator + (bigN n1){
    17         bigN ans;
    18         ans.length = max(n1.length,length);
    19         for(int i=0;i<ans.length;i++){
    20             ans.a[i] += a[i] + n1.a[i];
    21             ans.a[i+1] += ans.a[i]/10;
    22             ans.a[i]%=10;  
    23         }
    24         if(ans.a[ans.length]!=0) ans.length++;
    25         return ans;
    26     }
    27     bool operator < (bigN n1){//this是不是比n1小 
    28         if( length>n1.length ) return false;
    29         else if(length<n1.length) return true;
    30         for(int i=length-1;i>=0;i--){//从高位比到低位 
    31             if( a[i]>n1.a[i] ) return false;
    32             else if( n1.a[i]>a[i] ) return true;
    33         }
    34         //相等
    35         return false; 
    36     }
    37 }memo[55][55];
    38 ostream& operator<< (ostream& os,const bigN& x){
    39     for(int i=x.length-1;i>=0;i--) os<<x.a[i];
    40     return os;
    41 }
    42 
    43 bigN min(bigN n1,bigN n2){
    44     if(n1<n2) return n1;
    45     return n2;
    46 }
    47 
    48 int s[55];
    49 bigN dp(int i,int j){//前i个数字之间放j个加号的最小值
    50     //cout<<i<<" "<<j<<endl;
    51     if(memo[i][j].length!=0) return memo[i][j];
    52     if(i-1==j){
    53         bigN an;
    54         for(int i1=1;i1<=i;i1++) an=an+bigN(s+i1,1);
    55         return memo[i][j]=an;
    56     }
    57     if(j==0) return memo[i][j]=bigN(s+1,i);
    58     
    59     //枚举第j个加号放在第k个数字后 
    60     bigN ans; ans.length=100;
    61     for(int k=j;k<=i-1;k++){
    62         bigN cnt = dp(k,j-1)+bigN(s+k+1,i-k);
    63         ans = min(ans, cnt );
    64     }
    65 
    66     return memo[i][j]=ans;
    67 }
    68 
    69 
    70 int main(){
    71     int m;
    72     while( scanf("%d",&m)!=EOF ){
    73         string s1; cin>>s1;
    74         for(int i=0;i<s1.length();i++) s[i+1]=int(s1[i])-48;
    75         
    76         for(int i=0;i<=54;i++)
    77             for(int j=0;j<=54;j++) memo[i][j]=bigN();
    78             
    79         cout<<dp(s1.length(),m)<<endl;
    80     }
    81     
    82     return 0;
    83  } 
  • 相关阅读:
    window下cmd命令行的个人使用——集录
    前端之 —— node.js摸爬打滚之路(一)
    GIT常用命令以及作用【备忘】
    如何将Eclipse中的开源项目使用到Android Studio中
    2015读书目录
    Android4.0+锁屏程序开发——设置锁屏页面篇
    Android4.0+锁屏程序开发——按键屏蔽篇
    【光速使用开源框架系列】数据库框架OrmLite
    【光速使用开源框架系列】图片加载框架ImageLoader
    Android输入法部分遮挡UI的问题(与EditText框相切)
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9363582.html
Copyright © 2011-2022 走看看