NYOJ 整理图书(动态规划)
2016-05-17 18:33
253 查看
描述
小明是图书鹳狸猿,他有很多很多的书堆在了一起摆在了架子上,每摞书是横着放的,而且每摞书是订好的
是一个整体,不可分开,(可以想象架子是一条直线),但是这些书高度却参差不齐,小明有强迫症,看不得不整齐
所以他想让这些书的高度形成一个非降序列他才舒心,可是这些书是有序的,所以他只能把其中的一摞书和他相邻的书装订在一起
形成一摞新的书,那么他最少的装订次数是多少呢
输入
多组测试数据,处理到文件结束
每组数据开始有一个n(1<=n<=1000)表示有n摞书
接下来一行是这n摞书的高度a[i],(1<=a<=10^5)(虽然这个高度有点扯淡)
输出
首先输出Case num : 表示第几组数据
接下来对于每组数据输出最少的装订次数
样例输入
5
8 2 7 3 1
1
100
样例输出
Case 1: 3
Case 2: 0
dp[i]表示前i本书所要的最小次数,叠成非降序列所需要的最小次数。答案即dp
,很简单因为有n本嘛。
先来分析一下这道题,这道题总体就是动态规划,是属于‘记录结果再利用’型的动态规划。就是本次(即第i个)的最优值依赖于前面所有以求出来的最大值,算法复杂度大致为O(n*n);
详解一下第i个时选择的策略,第i个可以单独1摞书,可以从第i个往前数2本放一摞,也可以从第i个往前数3本放一摞.....一次类推,设j<i and 0<j<i, 则可以考虑从第j个到第i个放一摞,所以dp[i]=dp[j-1]+i-j;(因为j到i一共有i-j+1本,只要叠i-j次);其实说白了就是根据当前点不断的枚举之前已经求出来的值。
代码实现的时候就是这样的,h[i]记录为当前最优最高方法下的最高的一摞书,所以第考虑前i个的时候要注意和要大于等于前面记录的h,所以边更新边记录。
AC代码:
小明是图书鹳狸猿,他有很多很多的书堆在了一起摆在了架子上,每摞书是横着放的,而且每摞书是订好的
是一个整体,不可分开,(可以想象架子是一条直线),但是这些书高度却参差不齐,小明有强迫症,看不得不整齐
所以他想让这些书的高度形成一个非降序列他才舒心,可是这些书是有序的,所以他只能把其中的一摞书和他相邻的书装订在一起
形成一摞新的书,那么他最少的装订次数是多少呢
输入
多组测试数据,处理到文件结束
每组数据开始有一个n(1<=n<=1000)表示有n摞书
接下来一行是这n摞书的高度a[i],(1<=a<=10^5)(虽然这个高度有点扯淡)
输出
首先输出Case num : 表示第几组数据
接下来对于每组数据输出最少的装订次数
样例输入
5
8 2 7 3 1
1
100
样例输出
Case 1: 3
Case 2: 0
dp[i]表示前i本书所要的最小次数,叠成非降序列所需要的最小次数。答案即dp
,很简单因为有n本嘛。
先来分析一下这道题,这道题总体就是动态规划,是属于‘记录结果再利用’型的动态规划。就是本次(即第i个)的最优值依赖于前面所有以求出来的最大值,算法复杂度大致为O(n*n);
详解一下第i个时选择的策略,第i个可以单独1摞书,可以从第i个往前数2本放一摞,也可以从第i个往前数3本放一摞.....一次类推,设j<i and 0<j<i, 则可以考虑从第j个到第i个放一摞,所以dp[i]=dp[j-1]+i-j;(因为j到i一共有i-j+1本,只要叠i-j次);其实说白了就是根据当前点不断的枚举之前已经求出来的值。
代码实现的时候就是这样的,h[i]记录为当前最优最高方法下的最高的一摞书,所以第考虑前i个的时候要注意和要大于等于前面记录的h,所以边更新边记录。
AC代码:
# include <cstdio> # include <cstring> # include <algorithm> using namespace std; int a[1010], dp[1010], h[1010], sum[1010]; int main(){ int i, j, k, n, t; t=0; while(scanf("%d", &n)!=EOF){ sum[0]=0; for(i=2; i<=n; i++){ dp[i]=2000000000; h[i]=-2000000000; } for(i=1; i<=n; i++){ scanf("%d", &a[i]); sum[i]=sum[i-1]+a[i]; } h[0]=0;h[1]=a[1];dp[1]=0;dp[0]=0; for(i=2; i<=n; i++){ for(j=1; j<=i; j++){ if(sum[i]-sum[j-1]>=h[j-1]){ if(dp[j-1]+i-j<dp[i]){ dp[i]=dp[j-1]+i-j; h[i]=sum[i]-sum[j-1]; } if(dp[j-1]+i-j==dp[i]){ h[i]=min(h[i], sum[i]-sum[j-1]); } } } } printf("Case %d: %d\n", ++t, dp ); } return 0; }
相关文章推荐
- GCD倒计时
- POJ 1502 MPI Maelstrom(Dijkstra)
- JVM类加载机制
- Objective-C类成员变量深度剖析
- Oracle自定义函数
- 领取任务
- Java面向对象小结
- 前端开发流程
- Python Tricks(三)—— 计算误分率
- 【leetcode】283. Move Zeroes
- AssetBundle5.3.4依赖包加载流程
- [转载]河北易县:黑恶势力称“霸”房地产市场 谁为其撑腰?
- 纯数字字符串判定
- CRM
- java中类的各种定义
- Windows下adb安装配置
- 求解LambdaMART的疑惑?
- Android AndroidStudio JSR/RET are not supported with computeFrames option
- Mac配置环境
- 自定义控件(继承系统控件,非自绘)