二解<花店橱窗布置>
来源:互联网 发布:shell编程简单题 编辑:程序博客网 时间:2024/06/10 14:41
花店橱窗布置题目见洛谷:https://www.luogu.org/problem/show?pid=1854
一.记忆化搜索
这个问题第一眼看上去,它就是一个当初深搜求组合数的方案数的变形,m个花瓶插n朵花,而且这几朵花的顺序先后顺序不变,求和最大.是否有点像m个数取n个数组合,这n个数保证小的在前,大的在后,只不过是输出方案数而非和呢.看看数据规模100以内,想想,裸搜是一定会TLE的,但还是大胆地搜试试,果然AC1个点,9个点超时。
想想这道题既然可以用动规解决,那在搜的过程中用适当的数组记下搜索产生的过程最优值,即记忆化搜索的方式对搜索剪枝也一定可以完成。于是采用了一个数组rem[101][101]来记录搜索过程中的最优值。如果之前对该第k朵花放至第t个花瓶及下方搜索完毕过,则直接返回rem[k][t],否则以搜索所有可能的情况,记录下最优值至rem[k][t]里。
以样例数据为例,记忆化搜索树图如下,辅助理解:
#include<iostream>#include<climits>#include<iomanip>using namespace std;int n,m;int flower[101][101];int rem[101][101],can[101][101];int dfs(int k,int t){ if(rem[k][t]!=0) return rem[k][t] ; if(k==n){ return rem[k][t] = flower[k][t]; } int ansM=INT_MIN,temp=0; for(int j = t+1;j<= m-(n-k)+1; j++){ temp = dfs(k+1,j) + flower[k][t]; if(ansM < temp){ ansM = temp; can[k][t] = j; } } rem[k][t] = ansM; return ansM; }int main(){ cin >> n >> m; for(int i = 1; i<= n; i++) { for(int j = 1; j<= m; j++) cin >> flower[i][j]; } cout << dfs(0,0) << endl; int x = INT_MIN,s=0; s = can[0][0]; cout << s << " "; for(int i = 1; i< n; i++) { cout << can[i][s] <<" "; s = can[i][s]; } cout << endl; return 0;}
二.动态规划
如图,可以看到是一个有向无环图,题目要求的是这个图的最长路径,一个比较好的算法是动态规划.对于第i束花放至第j个花瓶时的可能产生的最美值,实际是前i-1束花放至第i-1 ~ j-1之间的最优值 + flower[i][j].因此可以以放入的花束个数为阶段,动态规划状态转移方程为:dp[i][j] = max(dp[i][j],dp[i-1][k] + flower[i][j]),并同时记录这个最大值由哪个k来更新的,方便后期输出方案.
详细程序如下:
#include<iostream>#include<climits>using namespace std;int n,m;int flower[101][101],dp[101][101];int ans = INT_MIN,d=0;int v[101],ansv[101];int pat[101][101];int main(){ cin >> n >> m; for(int i = 1; i<= n; i++){ for(int j = 1; j<= m; j++) cin >> flower[i][j]; } for(int i = 1; i<= n; i++){ dp[1][i] = flower[1][i]; } for(int i =2; i<= n; i++) //i代表花束 { for(int j = i; j <= m-(n-i);j++){ for(int k = i-1; k< j; k++){ if(dp[i][j] < dp[i-1][k] + flower[i][j]) { dp[i][j] = dp[i-1][k] + flower[i][j]; pat[i][j] = k; } } } } int s; for(int i = n; i<=m; i++){ if(ans<dp[n][i]){ ans = dp[n][i]; s = i; } } cout << ans << endl; for(int i=n; i>= 1; i--){ v[i] = s; s = pat[i][s]; } for(int i=1 ;i <= n; i++){ cout << v[i] << " "; } return 0;}
…
阅读全文
0 0
- 二解<花店橱窗布置>
- 花店橱窗布置问题
- RQNOJ 花店橱窗布置
- 花店橱窗布置(IOI)
- 【DP】 花店橱窗布置
- IOI 花店橱窗布置
- 花店橱窗布置
- 花店橱窗布置【DP】
- P1854 花店橱窗布置
- 花店橱窗布置
- 【动态规划】花店橱窗布置
- DP之花店橱窗布置
- 【wikioi】1028花店橱窗布置
- [Tyvj 1124]花店橱窗布置
- 【CodeVS 1028】 花店橱窗布置
- 花店橱窗布置【动态规划】
- codevs 1028 花店橱窗布置
- 洛谷 P1854 花店橱窗布置
- mysql优化怎么做的?
- MySQL行级锁、表级锁、页级锁详细介绍
- Spring+redis 4、使用注解注意事项
- linux运维面试题
- 关于MYSQL的in,not in,exists,not exists等关键字简单易懂的理解与应用
- 二解<花店橱窗布置>
- 如何利用网管软件管控SNMP协议的网络设备
- tensorflow关于二维码的验证
- java 继承
- java 环境变量配置
- GPU渲染管线与shader
- iOS xib设置阴影
- Andorid N 最近任务管理器流程详解(二)
- Oracle ORA-04021 等待锁定对象时发生超时