在一个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个+号,使和最小: ",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 ",f[n][r]); // 输出最优值 }