题目描述:


输入格式:
输入文件的第一行是一个整数n(1<=n<=2000)n(1<=n<=2000)n(1<=n<=2000),表示数字个数;第二行一个整数m(1<=m<=n)m(1<=m<=n)m(1<=m<=n),表示回合数,接下来一行有n个不超过100001000010000的正整数,a1,a2,a3,⋯,ana1,a2,a3,\cdots,ana1,a2,a3,⋯,an表示原始序列,最后一行有n个不超过500500500的正整数,b1,b2,b3,⋯,bnb1,b2,b3,\cdots,bnb1,b2,b3,⋯,bn,表示每回合每个数字递减的值。

输入样例:
3
3
10 20 30
4 5 6

输出样例:
47


解题思路:

首先我们要有一个损失数值的概念。

我们先来思考一下,倘若 aia_iai​ 比 aja_jaj​ 先取走,并且 bi<bjb_i<b_jbi​<bj​,那么很显然,经过一轮后 aja_jaj​ 的值会下降 bjb_jbj​,损失的数值为 bjb_jbj​;若先取走 aja_jaj​ 再取走 aia_iai​,损失数值为 bib_ibi​因为 bi<bjb_i<b_jbi​<bj​,所以答案更优。

也就是说,bbb 值越大的数越先取走,我们的损失数值总和会降得越小,答案会更优。因此,我们先将 bbb 数组由大到小排序,然后在从左到右取 mmm 个数,即为最优取数方式。

由于 m≠nm\ne nm​=n,因此我们并非所有数都要取,因此需要一个动态规划的策略找到最优解。

设 fi,jf_{i,j}fi,j​ 表示在前 iii 个数中取 jjj 个数(即第 jjj 个回合)所能取到的最大数值。
若不取第 iii 个数字,那么这个状态等价于在前 i−1i-1i−1 个数中取 jjj 个数的最大值
若取第 iii 个数字,那么这个状态等价于在前 i−1i-1i−1 个数中取 j−1j-1j−1 个数的最大值,再加上 第 iii 个数第 jjj 个回合时的数值。
fi,j=max⁡{fi−1,j不选第i个数fi−1,j−1+ai−bi∗(j−1)选第i个数f_{i,j}=\max\begin{cases} f_{i-1,j}&不选第 i 个数\\ f_{i-1,j-1}+a_i-b_i*(j-1)&选第 i 个数\\ \end{cases} fi,j​=max{fi−1,j​fi−1,j−1​+ai​−bi​∗(j−1)​不选第i个数选第i个数​

然后就是重中之重!本人就是在这里栽倒了好多次。状态的初值必须要赋好,否则很容易DP错误!
这题中的初始状态有这些:

  1. fi,0=0i=1⋯nf_{i,0}=0~~~~~~~~~~~~~~~~~~~~~~~~i=1\cdots nfi,0​=0                        i=1⋯n
  2. fi,1=max⁡(ai)i=1⋯nf_{i,1}=\max(a_i)~~~~~~~~~~~~i=1\cdots nfi,1​=max(ai​)            i=1⋯n
  3. others为−∞others~为-\inftyothers 为−∞

这个状态在空间上还可以优化:fi,jf_{i,j}fi,j​ 只能从 fi−1,jf_{i-1,j}fi−1,j​ 推出来,因此我们可以把第一维省略掉。


CODE:

空间优化前:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
struct QWQ
{int a,b;
} e[2010];
bool cmp(QWQ a,QWQ b)
{return a.b>b.b;
}
int f[2001][2001]={0};
int main()
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>e[i].a;for(int i=1;i<=n;i++) cin>>e[i].b;sort(e+1,e+1+n,cmp);memset(f,-0x7f,sizeof(f));f[0][0]=0;f[1][1]=e[1].a;for(int i=2;i<=n;i++)f[i][1]=max(f[i-1][1],e[i].a);for(int i=1;i<=n;i++){for(int j=2;j<=min(i,m);j++)  //由于j=1的情况上面已经作为初始状态做了,就不能再做一次了,所以从2开始{f[i][j]=max(f[i-1][j],f[i-1][j-1]+e[i].a-e[i].b*(j-1));}}cout<<f[n][m];return 0;
}

空间优化后:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,m;
struct QWQ
{int a,b;
} e[2010];
bool cmp(QWQ a,QWQ b)
{return a.b>b.b;
}
int f[2001]={0};
int main()
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>e[i].a;for(int i=1;i<=n;i++) cin>>e[i].b;sort(e+1,e+1+n,cmp);memset(f,-0x7f,sizeof(f));for(int i=1;i<=n;i++){f[0]=0;  //任何个数字的第 0 回合都不会取到分数for(int j=m;j>=1;j--)  //这里为了保证f[j-1]为上一回合的,01背包的倒叙循环同理。{f[j]=max(f[j],f[j-1]+e[i].a-e[i].b*(j-1));}f[1]=max(f[1],e[i].a);   //任何个数字取一个都是选最大}cout<<f[m];return 0;
}

SSL 1653 数字游戏相关推荐

  1. 【动态规划】 数字游戏 (ssl 1653)

    数字游戏 题目大意: 有n个数,分别为a[1] (序号为1),a[2] (序号为2),a[3]-a[n],让你选m个数,每选一个数,就要减去已选个数(不算当前数)*b[i] (i为当前值的序号),所选 ...

  2. 用法 stl_51Nod 2160 数字游戏 STL基本用法

    目录 目录 1. 题目描述 1.1. Limit 1.2. Problem Description 1.3. Input 1.4. Output 1.5. Sample Input 1.6. Samp ...

  3. [蓝桥杯]PREV-23.历届试题_数字游戏

    问题描述栋栋正在和同学们玩一个数字游戏.游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈.栋栋首先说出数字1.接下来,坐在栋栋左手边的同学要说下一个数字2.再下面的一个同学要从上一个同学说的数字往 ...

  4. C语言经典小游戏---猜数字游戏 (包含C语言中如何实现随机数的生成)

    题目描述:输入1-100之间的数字,进行猜数字游戏,猜大猜小有提示,直至才对为止,游戏可以重复游玩. 算法思路: 1.用void函数分别写出菜单程序与游戏进程程序. 2.用switch-case-de ...

  5. 例题3-4 猜数字游戏的提示(Master-Mind Hints, UVa 340)

    实现一个经典"猜数字"游戏.给定答案序列和用户猜的序列,统计有多少数字位置正确 (A),有多少数字在两个序列都出现过但位置不对(B). 输入包含多组数据.每组输入第一行为序列长度n ...

  6. https、SSL与数字证书介绍

    在互联网安全通信方式上,目前用的最多的就是https配合ssl和数字证书来保证传输和认证安全了.本文追本溯源围绕这个模式谈一谈. 名词解释 首先解释一下上面的几个名词: https:在http(超文本 ...

  7. c语言猜数字游戏用while,【C语言基础】有趣的猜数字游戏。(while循环,if语句,switch语句)...

    要求:猜数字游戏的实现.代码如下:#include #include #include void menu() { printf("***************************** ...

  8. python猜年龄代码_python入门教程NO.7用python来写一个猜数字游戏

    python入门教程 本文涉及的python基础语法为while循环 #python#3中while语句常常被用于循环执行某个程序,任何非0和非空null的值,都会被条件判断为True while 条 ...

  9. Go-实现猜数字游戏代码

    实现猜数字游戏代码 1 package main 2 3 import ( 4 "fmt" 5 "math/rand" 6 "time" 7 ...

  10. 挣值管理不是搞数字游戏

    摘要: 要考PMP(Project Management Professional ),挣值管理是必考的知识.软件项目有很大的特殊性,不少人认为挣值管理不太适用于软件项目.挣值管理相关资料也比较超多, ...

最新文章

  1. 【工具使用系列】关于 MATLAB 液压元件,你需要知道的事
  2. 调用python接口并画图_【PySpark源码解析】教你用Python调用高效Scala接口
  3. C语言学习笔记--位运算
  4. 深交所a股证券代码_深市和沪市的股票代码应该怎么区别?
  5. 电气工程及其自动化学不学c语言,电气工程及其自动化学什么 就业方向有哪些...
  6. python同时赋值_python同时给多个变量赋值
  7. C#动态调用WCF接口,两种方式任你选。
  8. 第一次没有写出来的SQL
  9. 2020互联网大厂中秋礼盒PK!我酸了!
  10. 如何修改Maven本地仓库位置
  11. 英雄联盟官网服务器状态查询,官方新功能:各大区服务器状态可查询!
  12. Beetl的基本用法
  13. Sketch中的快捷键总结
  14. 我的世界服务器如何修复报错,我的世界18w30a发布 修复1.13众多BUG
  15. 【总结】PHP常见面试题汇总(一)。。。
  16. vue分类筛选方法,filer
  17. Docker file镜像
  18. 修改freeradius服务器配置
  19. 易微联vs602m蓝牙双模说明引脚定义
  20. android 毕业设计题目

热门文章

  1. 我要偷偷的学Python,然后惊呆所有人(第一天)
  2. Windows电脑添加打印机
  3. 活动单导学计算机课,教学中“活动单导学”教学模式的反思
  4. android badgeview activity不显示,关于BadgeView遇到的一个奇怪的问题和解决办法
  5. android 浏览器 该网站的安全证书有问题
  6. 反函数的导数 基本初等函数的求导公式
  7. 双线威廉指标_电影中的技术失败是新的威廉尖叫
  8. 9.3. Mathematical Functions and Operators
  9. spark的fold函数理解
  10. mac系统Airtest环境安装教程