1. 程式人生 > >動態規劃之最大K乘積(實驗報告版)

動態規劃之最大K乘積(實驗報告版)

西 安 郵 電 大 學

            (計算機學院)

課內實驗報告

實驗名稱:     最大K乘積

    專業名稱: 電腦科學與技術

班    級: 計科1202

    學生姓名:   ——————

學號(8位):————————

指導教師:    ————————

實驗日期:       2015512

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]);

}

}