數字串新增號求最小和
阿新 • • 發佈:2018-12-30
轉載至https://blog.csdn.net/liuchaohs/article/details/53186735
題目描述
有一個由數字1,2,...,9組成的數字串(長度不超過200),問如何M(1<=M<=20)個加號插入這個數字串中,使得所形成的算術表示式的值最小。
注意:(1)加號不能加在數字串的最前面或最末尾,也不應有兩個或兩個以上的加號相鄰;
(2)M保證小於數字串的長度。
例如:數字串79846,若需加入兩個加號,則最佳方案是79+8+46,算術表示式的值是133。
輸入格式:從鍵盤讀入輸入檔名。數字串在輸入檔案的第一行行首(數字串中間無空格且不換行),M的值在輸入檔案的第二行行首。
輸出格式:在螢幕上輸出最小的和
解題思路:
規 劃 方 程 :
Dp[p,x] = MIN { dp[k,x-1] + NUM[K,p] } (x<=K<=p-I)
邊 界 值 :dp [p, 0 ]: = NUM[0, p]
Dp[p,x ]表 示前 p個 數 字 中 添 上 x個 加 號 後 得 到 的 最 小 值 。
NUM[x,y ]表 示數 字 串 [x.y) 的 數
解題程式碼:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=200; const int inf=0x3f3f3f3f; int dp[N][N]; int num[N][N]; int m; char ch[N]; int NUM(int k,int p){ if(num[k][p]!=-1) return num[k][p]; int sum=0; for(int i=k;i<p;i++){ sum=sum*10+ch[i]-'0'; } num[k][p]=sum; return sum; } int DP(int p,int x){ if(dp[p][x]!=-1) return dp[p][x]; if(x==0){ dp[p][0]=NUM(0,p); return dp[p][0]; } dp[p][x]=inf; for(int i=p-1;i>=x;i--){ dp[p][x]=min(dp[p][x],DP(i,x-1)+NUM(i,p)); } return dp[p][x]; } int main(){ memset(dp,-1,sizeof(dp)); memset(num,-1,sizeof(num)); scanf("%s",ch); scanf("%d",&m); int len=strlen(ch); printf("%d\n",DP(len,m)); return 0; }