1. /*
  2. ///题解写的很认真,如果您觉得还行的话可以顶一下或者评论一下吗?
  3. 思路:
  4. 这题复杂在要取前k大的结果,如果只是取最大情况下的金币和,直接
  5. 动态规划递归就可以,可是前k大并不能找出什么公式,所以在二元数组的基础上再并上一个vector
  6.  
  7. 首先:初始化最左边和最上边(动态规划的边缘)
  8. 其次:找出关系,每个格的金币只可能来自上边或者右边(动态规划的状态方程)
  9. 然后:我们要找的是前k大金币总和而不是前1大,所以准备vector存更多情况
  10. 然后:每次处理时,当前格子除了拿上自己的金币外,还要接受前面或者上边送来
  11. 的一袋袋金币这些金币,这些袋子有大有小,尽可能挑出前k大的袋子(如果没有
  12. k那么多就全部挑出来),然后当前格子最多接受k+k袋金币(上面的k和左边的k)
  13. 接受时边接受边排序,那么下次当前格子附近的格子要调用这个格子的金币袋子
  14. 情况时找出前k大即可
  15. 最后:f[m][n]这个最右下角的格子可能积累了一堆金币,从后往前(从大到小)挑出
  16. k个袋子即可
  17.  
  18. */
  19. //一个学长(栋神)出的题
  20. #include<bits/stdc++.h>
  21. #define ll long long
  22. using namespace std;
  23. const ll maxn=;
  24. vector<ll>f[maxn][maxn];//f向量用来存每个位置前k大的总金币
  25. ll a[maxn][maxn];//a数组用来存入数据
  26. int main()
  27. {
  28. ///输入环节
  29. ll m,n,k;
  30. cin>>m>>n>>k;
  31. for(ll i=;i<=m;i++)
  32. for(ll j=;j<=n;j++)
  33. scanf("%lld",&a[i][j]);//输入金币情况
  34. ///处理环节
  35. f[][].push_back(a[][]);
  36. //先向f向量中添加初始金币
  37. //同样的,接下来两个for分别初始化向量左边和上面两个边界的金币数
  38. for(ll i=;i<=m;i++)
  39. f[i][].push_back(a[i][]+(f[i-][])[]);
  40. for(ll i=;i<=n;i++)
  41. f[][i].push_back(a[][i]+(f[][i-])[]);
  42. //因为到最左竖和最上横分别只有一条路径,所以很好处理
  43.  
  44. ///接下来的向量f[i][j]会一直保持从小到大的排列顺序
  45. for(ll i=;i<=m;i++)
  46. for(ll j=;j<=n;j++)//两个for循环遍历剩下情况
  47. {
  48. //对f[i][j]的上面那格分析
  49. if(k<=f[i-][j].size())//如果要求的k比现在有的元素少
  50. //即如果k比当前vector内元素数目小的情况
  51. for(ll x=f[i-][j].size()-;x>=f[i-][j].size()-k;x--)
  52. {//从f[i-1][j]从后往前挑出k个数(也就是最大的k个数),分别加上a[i][j],塞入f[i][j]中
  53. //这让f[i][j]增加了新的元素,但f[i][j]依然是从小到大排序(为后面服务)
  54. (f[i][j]).insert(upper_bound(f[i][j].begin(),f[i][j].end(),(f[i-][j])[x]+a[i][j]),(f[i-][j])[x]+a[i][j]);
  55. }
  56. else//如果vector内元素数目小,还不够k多的情况
  57. for(ll x=f[i-][j].size()-;x>=;x--)
  58. {//同上
  59. (f[i][j]).insert(upper_bound(f[i][j].begin(),f[i][j].end(),(f[i-][j])[x]+a[i][j]),(f[i-][j])[x]+a[i][j]);
  60. }
  61. //对f[i][j]的左边那格分析
  62. ///第一个if else是配套的,只执行一个,这里又是一套if else,只执行一个
  63. //那么每次循环就处理一次上方,处理一次左边
  64. if(k<=f[i][j-].size())//类似于上面,不再叙述
  65. for(ll x=f[i][j-].size()-;x>=f[i][j-].size()-k;x--)
  66. {
  67. f[i][j].insert(upper_bound(f[i][j].begin(),f[i][j].end(),(f[i][j-])[x]+a[i][j]),(f[i][j-])[x]+a[i][j]);
  68. }
  69. else
  70. for(ll x=f[i][j-].size()-;x>=;x--)
  71. {
  72. f[i][j].insert(upper_bound(f[i][j].begin(),f[i][j].end(),(f[i][j-])[x]+a[i][j]),(f[i][j-])[x]+a[i][j]);
  73. }
  74. }
  75. for(ll i=f[m][n].size()-;i>=f[m][n].size()-k;i--)
  76. printf("%lld ",(f[m][n])[i]);
  77. //从后往前数k个数,分别输出(即在f[m][n]找出最大的k个数)
  78. }

前k大金币(动态规划,递推)的更多相关文章

  1. 最长上升子序列(动态规划递推,LIS)

    1759:最长上升子序列 题目: 总时间限制: 2000ms 内存限制: 65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的 ...

  2. 最大子段和(洛谷P1115,动态规划递推)

    洛谷题目链接 题目赋值出来格式有问题,所以我就只放题目链接了 下面为ac代码 #include<bits/stdc++.h> #define ll long long using name ...

  3. 7617:输出前k大的数

    7617:输出前k大的数 查看 提交 统计 提问 总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 给定一个数组,统计前k大的数并且把这k个数从大到小 ...

  4. 输出前 k 大的数

    总时间限制: 10000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入 第一行包含一个整数n,表示数组的大小 ...

  5. 牛客第六场 J.Heritage of skywalkert(On求前k大)

    题目传送门:https://www.nowcoder.com/acm/contest/144/J 题意:给一个function,构造n个数,求出其中任意两个的lcm的最大值. 分析:要求最大的lcm, ...

  6. (算法)前K大的和

    题目: 1.有两个数组A和B,每个数组有k个数,从两个数组中各取一个数加起来可以组成k*k个和,求这些和中的前k大. 2.有N个数组,每个数组有k个数,从N个数组中各取一个数加起来可以组成k^N个和, ...

  7. 快速排序算法的实现 && 随机生成区间里的数 && O(n)找第k小 && O(nlogk)找前k大

    思路:固定一个数,把这个数放到合法的位置,然后左边的数都是比它小,右边的数都是比它大 固定权值选的是第一个数,或者一个随机数 因为固定的是左端点,所以一开始需要在右端点开始,找一个小于权值的数,从左端 ...

  8. 输出前k大的数

    总时间限制: 10000ms单个测试点时间限制:1000ms内存限制:65536kB(noi) 描述 给定一个数组,统计前k大的数并且把这k个数从大到小输出. 输入 第一行包含一个整数n,表示数组的大 ...

  9. BZOJ2006:超级钢琴(ST表+堆求前K大区间和)

    Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...

随机推荐

  1. my.os.ClickThisWindow.ClickThisPoint.py

    my.os.ClickThisWindow.ClickThisPoint.py

  2. 安装linux系统-CentOS-6.8-x86_64-minimal.iso

    1: 2: 3:单击[Next]继续安装. 4:安装语言,选择[Chinese(Simplified)(中文(简体))]菜单,单击[Next]继续. 5:系统键盘,选择[美国英语式]菜单,单击[下一步 ...

  3. Interfaces (C# Programming Guide)

    https://msdn.microsoft.com/en-us/library/ms173156.aspx An interface contains definitions for a group ...

  4. 【PA 2014】Kuglarz

    [题目链接]            点击打开链接 [算法]            sum[i]表示前i个杯子中,杯子底下藏有球的杯子总数            那么,知道[i,j]这段区间中,藏有球的 ...

  5. Linux的文件搜索命令(locate ,find,grep,find命令和)

    刚开始学Linux,这是关于Linux文件搜索命令,就目前,尽我所能把他写全一点,后期随时补充 文件搜索命令 一.locate命令 二.find命令 三.grep命令 四.find命令和grep命令的 ...

  6. C# 简单实现直线方程,抛物线方程(转载)

    http://www.cnblogs.com/hsiang/archive/2017/01/17/6294864.html 本例子是简单的在WinForm程序中实现在坐标系中绘制直线方程,抛物线方程, ...

  7. E20170528-ts

    partial   adj. 部分的; 偏爱的; 偏袒的; 钟爱的; form   n. 表格; 方式; 形状,形式; 外形 annotate   vt. 注解,注释; n. 注释者; annotat ...

  8. Linux 上安装 Node.js

    Linux 上安装 Node.js 直接使用已编译好的包(在个人阿里云服务器47.100.6.106上安装) Node 官网已经把 linux 下载版本更改为已编译好的版本了,我们可以直接下载解压后使 ...

  9. Avito Code Challenge 2018 A~E

    A. Antipalindrome 还以为是什么神dp结果就是分情况讨论啊 原串是一串一样的字符的话输出0,是回文串的话输出n-1,否则直接输出原串长度 #include<iostream> ...

  10. [Swift]关键字:Self、self与super

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...