在一个n位整数a中插入r个加号,将它分成r+1个整数,找出一种加号的插入方法,使得这r+1个整数的和最小。

// 在一个数字串中插入r个+号,使和最小    
#include <stdio.h> 
#include <string.h> 
void main() { 
char sr[16];   
int n,i,j,k,u,r,b[16],t[16],c[16][16];  
double  f[17][17],d;   
printf("请输入整数:"); 
scanf("%s",sr);  
n=strlen(sr);   
printf("请输入插入的+号个数r:");  
scanf("%d",&r); 
 if(n<=r)     {
printf("  输入的整数位数不够或r太大! ");     
return;}   
printf("在整数%s中插入%d个+号,使和最小:\n",sr,r);  for(d=0,j=0;j<=n-1;j++)    
b[j]=sr[j]-48;             // 把输入的数串逐位转换到b数组    for(i=1;i<=n;i++)  
for(j=1;j<=r;j++)  
f[i][j]=1e16; 
for(d=0,j=1;j<=n;j++)     {
d=d*10+b[j-1];          // 把b数组的一个字符转化为数值      
 f[j][0]=d;              // f[j][0]赋初始值       
}   
for(k=1;k<=r;k++)  
for(i=k+1;i<=n;i++)  
for(j=k;j<i;j++)     {
for(d=0,u=j+1;u<=i;u++)        
d=d*10+b[u-1];      
if(f[i][k]>f[j][k-1]+d)          // 递推求取f[i][k]          
{f[i][k]=f[j][k-1]+d;         
c[i][k]=j;        }     }   
t[r]=c[n][r];   
for(k=r-1;k>=1;k--)     
t[k]=c[t[k+1]][k];                // 逆推出第k个+号的位置t[k]    t[0]=0;t[r+1]=n;  
for(k=1;k<=r+1;k++)     {
for(u=t[k-1]+1;u<=t[k];u++)        
printf("%c",sr[u-1]);          // 输出最优解       
if(k<r+1)       
 printf("+");     }   
printf("=%.0f\n ",f[n][r]);         // 输出最优值    
}