動態規劃之最大K乘積(實驗報告版)
西 安 郵 電 大 學
(計算機學院)
課內實驗報告
實驗名稱: 最大K乘積
專業名稱: 電腦科學與技術
班 級: 計科1202
學生姓名: ——————
學號(8位):————————
指導教師: ————————
實驗日期: 2015年5月12日
1.
上機題目及實驗環境
1.1上機題目:最大k乘積問題
1.2實驗環境:
作業系統:Microsoft Windows XP
軟體平臺:Microsoft Visual C++
2. 演算法設計與分析
設w(h,k) 表示從第1位到第k位所組成的十進位制數;
設m(i,j)表示前i位分成j段所得的最大乘積;
則可得到如下經典的DP方程:
if(j==1)
m(i,j) = w(1,i) ;
if(j >1 && j<=i )
m(i,j) = m(d,j-1)*w(d+1,i) //其中: 1<=d< i (即從1開始一直到i-1 中找最大值
if(i < j)
m(i,j) = 0 ;
//i一直小於等於n,j一直小於等於k
3. 核心程式碼
void maxdp(int n,int k,int *a)
{ int i,j,d;
long temp,max;
for(i=1; i<= n ; i++) //分成1段
m[i][1] = w[1][i];
for(i=1 ; i<= n ; i++) //DP 過程
for(j=2; j<= k ; j++)
{
max = 0;
for(d=1; d < i ; d++)
if ( (temp = m[d][j-1]*w[d+1][i]) > max)
max = temp ;
m[i][j] = max ;
}
}
4. 執行與除錯
5. 結果分析和小結
(1)對結果的分析。分析結果可以採用圖或者表的形式給出。
n |
k |
num |
最大K乘積 |
2 |
1 |
15 |
15 |
4 |
2 |
1123 |
336 |
5 |
2 |
11023 |
3306 |
(2)本次上機實驗的收穫、心得體會。
===
附錄(Java原始碼)
package com.mhc.learn;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
/**
* 最大K乘積
* @author mhc
*
*/
public class exp3 {
static int k,n,num;
static int M=10;
/**
* 從檔案中解析出三個整數
*/
public void readFile(){
FileInputStream fis = null;
try {
fis = new FileInputStream(new File("/home/mhc/test/input.txt"));
byte[] buf = new byte[1024];
int read = -1;
StringBuffer sb = new StringBuffer();
while ((read= fis.read(buf))!=-1) {
sb.append(new String(buf));
}
String string = new String(sb);
n =Integer.parseInt( string.split(" ")[0]);
string = string.split(" ")[1];
k = Integer.parseInt(string.split("\n")[0]);
num = Integer.parseInt(string.split("\n")[1]);
System.out.println("n="+n);;
System.out.println("k="+k);;
System.out.println("num="+num);;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 寫檔案
*/
public void writeFile(int k){
FileWriter fos = null;
try {
fos = new FileWriter(new File("/home/mhc/test/output.txt"), false);
fos.write(Integer.toString(k));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* eg:
* n=4 k=2時
* m(4,2)=max(m(1,1)*w(2,4),m(2,1)*w(3,4),m(3,1)*w(4,4));
*/
public void maxDp(int n,int k,int [][]w,int [][] m){
int temp = 0;
for (int i = 1; i <=n ; i++) {
m[i][1] = w[1][i];
}
//DP過程
for (int i = 1; i <=n; i++) {
for (int j = 2; j <=k; j++) { //分成j段
int max = 0;
for (int d = j-1; d < i; d++) {
if((temp=m[d][j-1]*w[d+1][i])>max){
max = temp;//替換最大的值
}
}
m[i][j] = max;
}
}
for (int i = 1; i <=n; i++) {
for(int j=1;j<=n;j++){
System.out.print(m[i][j]+" ");
}
System.out.println();
}
}
public static void main(String[] args) {
exp3 e = new exp3();
e.readFile();
//將num分解為單個數字
int [] a = new int[M];
int x = num,n1=n;
System.out.println(x);
while(x!=0){
a[n1--] = x%10;//a[0]中未存值
x /=10;
}
//初始化矩陣
int [][] w = new int[M][M];
for (int i = 0; i < w.length; i++) {
w[i][i] = a[i];
for (int j = i+1; j <=n; j++) {
w[i][j] = w[i][j-1]*10 + a[j];
}
}
int [][] m = new int[M][M];
e.maxDp(n, k, w, m);
System.out.println("最大乘積是:"+m[n][k]);
e.writeFile(m[n][k]);
}
}