动态规划k乘积问题

2020-04-17 00:40

西安邮电大学

(计算机学院)

课内实验报告

实验名称:动态规划k乘积问题

专业名称:

班级: 学生姓名:

学号(8位): 指导教师:

实验日期:2016年月日

一. 实验目的及实验环境

实验目的: 熟悉并掌握贪心算法 实验环境: windows7 vc6.0编译器

二. 实验内容 题目描述:

设I是一个n位十进制整数。如果将I划分为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积,试设计一个算法,对于给定的I和k,求出I的最大k乘积。 算法设计:

对于给你定的I和看k,计算I的最大k乘积问题。 数据输入:

由文件input.txt 提取输入数据。文件的第1行中有2个正整数n和k。正整数n是序列的长度,正整数k是分割的段数。在接下来的一行中是一个n位十进制整数。

结果输出:

将计算计算结果输出到文件output.txt,文件第一行中的数是计算出的最大k乘积。

三.方案设计

1. 分析最优解的结构

为了方便起见,设I(s,t)是I的由s位开始的t位数字组成的十进制数,R(i,j)表示I(0,i)的j乘积。第j段的起始位置为第w位,1<w≤j。则有如下关系

R(i,j) = R(i,j-1)×I(w,j-w)

要使R(i,j)最大,则R(i,j-1)也是最大,所以最大K乘积问题的最优解包含其子问题的最优解。

2. 建立递归关系

设MaxI[i][j]表示I(0,i)的最大j乘积,则原问题的最优值为MaxI[n][k]。 当k=1时,MaxI[n][1] = I(0,n);

当k≠1时,可利用最优子结构性质计算MaxI[n][k], 若计算MaxI[n][k]的第k段的起始位置为第w位,1<w≤j,则有MaxI[n][k] = MaxI[w][k-1]×I(w,n-w)。由于在计算时并不知道第k段的起始位置w,所以w还未定。不过w的值只有n-k+2种可能,即k-1≤w≤n。所以MaxI[n][k]可以递归地定义为

I(0,n) k=1

MaxI[n][k] = max MaxI[w][k-1]×I(w,n-w) k≠1

MaxI[n][k]给出了最优值,同时还确定了计算最优的断开位置w,也就时说,对于这个w有 MaxI[n][k] = MaxI[w][k-1]×I(w,n-w)

若将对应于MaxI[n][k]的断开位置w记为demarcation[n][k]后,可递归地由 demarcation[n][k]构造相应的最优解。

四.测试数据及运行结果

正常测试数据(3组)及运行结果;

输入5位的数,分成3段

输入6位的数,分6段

五.总结

1.实验过程中遇到的问题及解决办法; 2.对设计及调试过程的心得体会。

六.附录:源代码(电子版)

#include #include #include #define MAXN 51 #define MAXK 10

//m[i][j]表示1~i十进制位分成j段所得的最大乘积 long m[MAXK][MAXN]={{0,0}} ;

//w[i][j]表示i~j十进制位所组成的十进制数 long w[MAXN][MAXN]={{0,0}} ; int leaf[MAXN][MAXN] = {{0,0}};

void maxdp(int n,int k,int *a) { int i,j,d; long temp,max; for(i=1; i<= n; i++){ //分成一段 m[i][1] = w[1][i]; } for(i=2 ; i<= n ; i++){ //DP 过程 for(j=2; j<= k ; j++){ max = 0; for(d=1; d < i ; d++){ //Test printf(\-----------\ if ( (temp = m[d][j-1]*w[d+1][i]) > max){ max = temp ; leaf[i][j]=d; } } m[i][j] = max ; printf(\ } } printf(\ for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ printf(\ } printf(\

} printf(\ for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ printf(\ } printf(\ } }

//输出分割后的K个数

void print_foot(int *data, int n, int k) { int d, i; int stack[256]; int top = 0; int tmp; tmp = n; while ((tmp = leaf[tmp][k]) > 0) { stack[top++] = tmp; k--; } printf(\ i = 1; while ((--top) >= 0) { tmp = stack[top]; for ( ; i <= tmp; i++) { printf(\ } printf(\ \ } for (; i <= n; i++) { printf(\ } printf(\ }

int main(void) { int n,k,i,j; int a[MAXN]={0},la=0; char c ; scanf(\ //input n, k while ( ( c=getchar() )!='#'){ //read integer a[++la] = c-'0' ; } for(i=1 ; i<= n; i++){ w[i][i]= a[i] ; for(j=i+1 ; j<= n; j++) w[i][j] = w[i][j-1]*10 + a[j] ; } for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ printf(\ } printf(\ } maxdp(n,k,a) ; printf(\ print_foot(a, n, k); return 0; }


动态规划k乘积问题.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:西安建筑科技大学处室文件-西安建筑科技大学-教务处 - 图文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: