和谐宿舍2
问题描述
我的某室友学过素描,墙上有n张他的作品。这些作品都是宽度为1,高度不定的矩形,从左到右排成一排,且底边在同一水平线上。
宿舍评比就要来了,为了及格,我们决定买不多于m块的矩形木板,把这些作品和谐掉。要求木板也从左到右排成一排,且底边与作品的底边在同一水平线上。
在能够把所有作品和谐掉的前提下,我们希望这些木板的面积和最小,问最小面积和。
宿舍评比就要来了,为了及格,我们决定买不多于m块的矩形木板,把这些作品和谐掉。要求木板也从左到右排成一排,且底边与作品的底边在同一水平线上。
在能够把所有作品和谐掉的前提下,我们希望这些木板的面积和最小,问最小面积和。
输入格式
第一行两个数n和m,表示作品数和木板数;
第二行n个数Hi,表示从左到右第i个作品的高度。
第二行n个数Hi,表示从左到右第i个作品的高度。
输出格式
一行一个数ans,表示答案。
样例输入
5 2
4 2 3 5 4
4 2 3 5 4
样例输出
22
数据规模和约定
对于30%的数据:1<=n,m<=10;
对于100%的数据:1<=n,m<=100,1<=Hi<=10000。
对于100%的数据:1<=n,m<=100,1<=Hi<=10000。
1 import java.util.*; 2 3 public class Main { 4 5 public static void main(String args[]) { 6 Scanner sc = new Scanner(System.in); 7 int n = sc.nextInt(); 8 int m = sc.nextInt(); 9 int[] len = new int[n+1]; //存放作品的实际高度 10 int[][] mlen = new int[n+1][n+1]; 11 int [][] area = new int[n+1][m+1]; //存放最小的面积 12 13 for(int i = 1; i <= n; ++i) { //存放输入的值 14 len[i] = sc.nextInt(); 15 mlen[i][i] = len[i]; 16 } 17 18 for(int i = 1; i <= n; ++i) { //存入 相比较之下,比较大的值 19 for(int j = i+1; j <= n; ++j) { 20 mlen[i][j] = Math.max(mlen[i][j-1], len[j]); 21 } 22 23 } 24 25 for(int i = 1; i <= n; ++i) { //如果只有一块木板,就是当前最大值乘数量 26 area[i][1] = mlen[1][i] * i; 27 } 28 29 for(int i = 1; i <= n; ++i) { //-----------分界线---------- 30 for(int j = 2; j <= m && j <= i; ++j) { 31 area[i][j] = 1000000; 32 for(int k = 1; k <= (i-j+1); ++k) { //从前面一副作品一块木板(j-1)开始,到后面最后一副作品一块木板 33 area[i][j] = Math.min(area[i][j], area[i-k][j-1] + k * mlen[i-k+1][i]); 34 } 35 } 36 } 37 38 System.out.print(area[n][m]); 39 } 40 }
这道动态规划还是比较基础的,但是有比较多的细节需要注意。