上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下数字字符串
一、标题:
给出一个数字(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”