100道动态规划——13 UVA 10163 Storage Keepers 有约束条件下的DP,递推,不能使用结构体作为基本单位
2016-11-16 16:32
316 查看
这道题目,我需要和另外一道题目来进行比较。
UVA 12563 这是我的题解:http://blog.csdn.net/good_night_sion_/article/details/53187701
在上面那一道DP里面,我的做法是利用一个结构体数组来储存当前的最优解,因此我联想到这一道题目应该也可以定义一个结构体数组来解决问题。
可是我错了,这道题目是不能那样解决的,也就是说,你定义一个二元组,以安全系数为第一优先级,资金为第二优先级来递推的话,是得不到正确答案的。
为什么?
关键在于第一优先级的单调性。
在12563里面,我们可以发现,唱的歌曲只能是增加,不会是减少的。因此这样那样定义没有问题。
但是在这里,第一优先级——安全系数并不是单调的。
比方说你前i个人看守前j个仓库的安全系数可能达到k,但是你m个人看守n个仓库的安全系数就不一定是k了,有可能小于k,但是在之前我们只会保留安全系数最大的解,这就导致有状态会丢失。
给一组数据
3 3
9 5 4
这样的话,定义结构体的做法是得不到正确答案的。
这就是我想说的,定义结构体的做法不能得到正确答案。
我在网上看到的题解,发现有两种,第一种是二分安全系数k,求出最大的安全系数,然后再DP找最小的值。第二种是k和最小的钱都用DP找。
我这里采用的是两种都是DP的做法。
我觉得状态的定义还是很好想到的,定义dp[i][j]表示前i个人看守前j个仓库的最大安全系数。
然后dp[i][j]的转移就是 min(dp[i-1][j],dp[i-1][k]+security[i]/(j-k)0<=k<j。通过这个求出最大的安全系数K
我们继续求最少的钱,dp[i][j]表当前的安全系数大于等于K的时候前i个人看守前j个仓库的最小花费
同样枚举k,dp[i][j]=min(dp[i-1][j],dp[i-1][k]+security[i])0<=k<j&&security[i]/(j-k)>=K,因为dp[i][j]的安全系数已经大于等于K了,只要保证secur[i]/(j-k)大于等于K就好。
然后仔细琢磨一下边界条件就好,我觉得已经到这一步了,边界条件已经不是很难的事情了。
UVA 12563 这是我的题解:http://blog.csdn.net/good_night_sion_/article/details/53187701
在上面那一道DP里面,我的做法是利用一个结构体数组来储存当前的最优解,因此我联想到这一道题目应该也可以定义一个结构体数组来解决问题。
可是我错了,这道题目是不能那样解决的,也就是说,你定义一个二元组,以安全系数为第一优先级,资金为第二优先级来递推的话,是得不到正确答案的。
为什么?
关键在于第一优先级的单调性。
在12563里面,我们可以发现,唱的歌曲只能是增加,不会是减少的。因此这样那样定义没有问题。
但是在这里,第一优先级——安全系数并不是单调的。
比方说你前i个人看守前j个仓库的安全系数可能达到k,但是你m个人看守n个仓库的安全系数就不一定是k了,有可能小于k,但是在之前我们只会保留安全系数最大的解,这就导致有状态会丢失。
给一组数据
3 3
9 5 4
这样的话,定义结构体的做法是得不到正确答案的。
这就是我想说的,定义结构体的做法不能得到正确答案。
我在网上看到的题解,发现有两种,第一种是二分安全系数k,求出最大的安全系数,然后再DP找最小的值。第二种是k和最小的钱都用DP找。
我这里采用的是两种都是DP的做法。
我觉得状态的定义还是很好想到的,定义dp[i][j]表示前i个人看守前j个仓库的最大安全系数。
然后dp[i][j]的转移就是 min(dp[i-1][j],dp[i-1][k]+security[i]/(j-k)0<=k<j。通过这个求出最大的安全系数K
我们继续求最少的钱,dp[i][j]表当前的安全系数大于等于K的时候前i个人看守前j个仓库的最小花费
同样枚举k,dp[i][j]=min(dp[i-1][j],dp[i-1][k]+security[i])0<=k<j&&security[i]/(j-k)>=K,因为dp[i][j]的安全系数已经大于等于K了,只要保证secur[i]/(j-k)大于等于K就好。
然后仔细琢磨一下边界条件就好,我觉得已经到这一步了,边界条件已经不是很难的事情了。
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; int n,m,arr[105],dp[35][105],l,y; int main(){ while(scanf("%d%d",&n,&m)&&n){ for(int i=1;i<=m;++i) scanf("%d",&arr[i]); for(int i=1;i<=n;++i) dp[0][i]=0; for(int i=0;i<=m;++i) dp[i][0]=0x3f3f3f3f; for(int i=1;i<=m;++i) for(int j=1;j<=n;++j){ dp[i][j]=dp[i-1][j]; for(int k=0;k<j;++k) dp[i][j]=max(dp[i][j],min(dp[i-1][k],arr[i]/(j-k))); } if(dp[m] ==0){ printf("0 0\n"); continue; } l=dp[m] ; for(int i=1;i<=n;++i) dp[0][i]=0x3f3f3f3f; for(int i=0;i<=m;++i) dp[i][0]=0; for(int i=1;i<=m;++i) for(int j=1;j<=n;++j){ dp[i][j]=dp[i-1][j]; for(int k=0;k<j;++k) if(arr[i]/(j-k)>=l) dp[i][j]=min(dp[i][j],dp[i-1][k]+arr[i]); } printf("%d %d\n",l,dp[m] ); } return 0; }
相关文章推荐
- UVA 12563 Jin Ge Jin Qu hao 在有约束条件下的DP,结构体作为基本单位
- 100道动态规划——24 UVA 1633 Dyslexic Gollum 状态压缩DP 挺好的题 因为窝没想到嘛
- 100道动态规划——36 UVA 1220 Party at Hali-Bula 树形DP 最大独立集 思考欠妥
- 100道动态规划——4 UVA 1331 Maximum Triangulation DP 计算几何
- 100道动态规划——3 UVA 2451 Brackets sequence 重构解 DP
- 100道动态规划——8 UVA 1631 Locker 递推,状态的定义以及状态转移方程
- 100道动态规划——26 UVA 12099 The Bookcase 状态的定义,递推,背包
- 100道动态规划——7 UVA 1630 folding 因为自己考虑的不周全WA了好几发。。。递推,KMP求子串周期
- UVA - 10163 - Storage Keepers(两次dp)
- UVA 10163 - Storage Keepers(dp)
- 在PLSQL中不能使用中文作为查询条件查询数据
- Storage Keepers - UVa 10163 dp
- 契约操作不能使用引用对象作为参数,只允许使用基本类型或数据契约
- UVA 10163 - Storage Keepers(dp)
- uva 11795 Mega Man's Mission(动态规划-状态压缩DP)
- 动态sql语句基本语法(字段名,表名,数据库名之类作为变量时,必须用动态SQL如ALTER TABLE中使用程序传递的参数)
- 动态规划入门(四)DP 基本思想与实现
- 动态规划的使用条件
- UVA 10163 Storage Keepers(两次DP)
- uva_10163 - Storage Keepers ( 普通DP )