数字字符串一道有道实习生笔试算法题分析

上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下数字字符串

    一、标题:

    给出一个数字(10,000~100,000,000),把这个数字拆分红4段,怎样使得4段的乘积最小。比如12345拆分红1*2*3*45=270, 10000=1*00*0*0=0。

 

    二、分析:

    这是一个型典的DP问题,设假dp[i][j]示表分红i段,且字符串指针动移到第j位时的最小乘积。  则明显i<=j.

    num[i][j]是数字中从第i个数字到第j个数字成组的数字。则可以到得DP的态状方程:

    数字和字符串

    dp[i-][j-k]示表当数字分红i-1段,且字符串指针动移第j-k位时的态状,因为(i-1)<=(j-k) ,所以要求k<=j-i+1。

    由态状方程很轻易得出对应的结果:

    

i\j 1 2 3 4 5
1 1 12 123 1234 12345
2 - 2 23 234 2345
3 - - 6 68 690
4 - - - 24 270
5 - - - - 120
    每日一道理
因为自信,在呀呀学语时,我靠着纤嫩的双腿,迈出人生的第一步;因为自信,我一次次将第一名的奖状高高举起;因为自信,我毫不吝惜地剪掉飘逸的长发,在运动场上展现风采……感谢自信,它给了我一双翅膀,让我在电闪雷鸣中去飞翔,在风雨中去搏击人生!

    本题是分红4段,很轻易到得dp[4][5]   出输结果是:270.

     

    三、代码如下:

#include<stdio.h>
#define MAXN ((1<<31)-1)  //极大值 
char A[10];
int num[10][10];
int dp[10][10]; 
//将对应字符串的制订置位转换为数整。 
int getInt(int i,int j)
{
    int temp=0,k;
    for(k=i-1;k<=j-1;k++) 
        temp=temp*10+(A[k]-'0'); 
    return temp;
}

int main()
{
  int i,j,k,len,temp,min;
  while(scanf("%s",A)!=EOF)
  {
    k=0;
    while(A[k]!='\0') k++;
    len=k;     //取得字符串的长度 
    if(len<5||len>9)  return 0;   //长度必须是5到9 
    for(i=1;i<=len;i++)
      for(j=i;j<=len;j++)    
        num[i][j]=getInt(i,j); 

    
    for(j=1;j<=len;j++)    dp[1][j]=getInt(1,j);  //初始化分割为1时的态状 
    for(i=2;i<=len;i++)
     for(j=i;j<=len;j++)
     {
       min=MAXN;
       for(k=1;k<=j-i+1;k++)
       {
         temp=dp[i-1][j-k]*num[j-k+1][j];
         if(temp<min)
            min=temp;
       }                
       dp[i][j]=min;  
       if(j!=len)
         printf("%d ",dp[i][j]);
       else printf("%d\n",dp[i][j]);                       
     }  
     printf("分红4段时,最小的分割方法是:%d\n",dp[4][len]);                      
  }
  return 0;   
}

    
 

     

文章结束给大家分享下程序员的一些笑话语录: 警告
有一个小伙子在一个办公大楼的门口抽着烟,一个妇女路过他身边,并对他 说, “你知道不知道这个东西会危害你的健康?我是说, 你有没有注意到香烟 盒上的那个警告(Warning)?”
小伙子说,“没事儿,我是一个程序员”。
那妇女说,“这又怎样?”
程序员说,“我们从来不关心 Warning,只关心 Error”

posted @ 2013-05-09 19:26  坚固66  阅读(154)  评论(0编辑  收藏  举报