当前位置: 首页 > news >正文

ABC-Index-(dp枚举方式优化)

D

题意:
就是给你一个数组,让你选一个长度为m的子序列,然后这个长度为m的子序列为vb数组,那么这个价值为i*vb[i]的总和。

思考:

  1. 这题有个简单版本就是连续数组,那么就直接每次拿一个仍一个,维护总和ans,一直更新最大值就可以了。
  2. 那么这个可以不连续的,n和m也都变成了2e3。那么很明显就只能dp了,最经典的dp定义就是dp[i][j]为到了第i个数字,取了j个数的价值。然后i从k转移再枚举一次,但是这样是O(n3)复杂度。
  3. 但是想到j只能用到j-1对吧,又是经典的优化。和这两题一样:CFdiv2-Chip Move 、牛客多校-Two Frogs。 然后就写了,第一维枚举选的第几个数,然后第二维枚举第i个点,那么dp[i]这一层可以更新下一层>=i的所有点,所以我就从前往后一直维护一个最大值就可以了。那么下一层的dp[i] = 这一层的前缀maxn+贡献。最后处理完对dp每个点取一个最大值就可以了。
  4. 但是发现例子:-1 -2 - 3 -4,是不对的。因为dp本来的状态应该是到第i个点,选了恰好j个数的代价,所以只有dp[0][0] = 0,剩下的都是-inf,但是我如果把第二维度优化掉,这样就会让dp[0][0-m] = 0了,这样就多了。所以可以对dp开二维,当然也可以只开dp和tp,但是maxn为0的时候只有最刚开始的时候。
直接二维:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
 
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;
 
int T,n,m,k;
int va[N];
int dp[M][M];
 
signed main()
{
	IOS;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>va[i];
	for(int i=0;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		dp[i][j] = -inf;
	}
	dp[0][0] = 0;
	for(int j=0;j<m;j++)
	{
		int maxn = -inf;
		for(int i=0;i<=n;i++)
		{
			dp[i][j+1] = maxn+(j+1)*va[i];
			maxn = max(maxn,dp[i][j]);
		}
	}
	int maxn = -inf;
	for(int i=1;i<=n;i++) maxn = max(maxn,dp[i][m]);
	cout<<maxn<<"\n";
	return 0;
}
滚动数组特判:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;

int T,n,m,k;
int va[N];
int dp[M];
int tp[M];

signed main()
{
	IOS;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>va[i];
	for(int i=0;i<=n;i++) dp[i] = tp[i] = -inf;
	for(int j=0;j<m;j++)
	{
		int maxn = -inf;
		if(j==0) maxn = 0; //只有i==0&&j==0也就是第一次的时候maxn = 0
		for(int i=0;i<=n;i++)
		{
			tp[i] = maxn+(j+1)*va[i];
			maxn = max(maxn,dp[i]);
		}
		for(int i=1;i<=n;i++) dp[i] = tp[i];
	}
	int maxn = -inf;
	for(int i=1;i<=n;i++) maxn = max(maxn,dp[i]);
	cout<<maxn<<"\n";
	return 0;
}

总结:
一定要搞清楚自己的dp状态定义,要确定好细节。

相关文章:

  • obj模型的格式
  • 设计模式:适配器模式(C++模式)
  • CGLIB 动态代理使用
  • Revit SDK:CreateFillPattern 创建填充样式
  • 当mybatisPlus与tk.mybatis遇到更新
  • sp.coo_matrix(), sp.eye()
  • linux虚拟机未建分区的情况下对磁盘进行扩容
  • 猿创征文|【数据结构】牛客网刷题
  • 【函数式编程】Java函数式编程学习
  • 基于springboot,vue旅游信息推荐系统
  • SSLError(MaxRetryError(‘HTTPSConnectionPool(host=\‘repo.anaconda.com\‘, port
  • vs生成dll且被java通过jna调用
  • DDD - 六边形架构和CQRS架构
  • 宠物寄养小程序实战教程02
  • 【计算机网络】运输层习题(谢希仁)(1)
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 【刷算法】从上往下打印二叉树
  • Angularjs之国际化
  • CAP 一致性协议及应用解析
  • ECS应用管理最佳实践
  • HTML中设置input等文本框为不可操作
  • JAVA 学习IO流
  • JavaScript函数式编程(一)
  • Octave 入门
  • Python连接Oracle
  • SwizzleMethod 黑魔法
  • vue 个人积累(使用工具,组件)
  • vuex 学习笔记 01
  • vue的全局变量和全局拦截请求器
  • webpack+react项目初体验——记录我的webpack环境配置
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 电商搜索引擎的架构设计和性能优化
  • 计算机常识 - 收藏集 - 掘金
  • 简单实现一个textarea自适应高度
  • 物联网链路协议
  • 鱼骨图 - 如何绘制?
  • HanLP分词命名实体提取详解
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • #《AI中文版》V3 第 1 章 概述
  • #单片机(TB6600驱动42步进电机)
  • (bean配置类的注解开发)学习Spring的第十三天
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (第二周)效能测试
  • (二)linux使用docker容器运行mysql
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)ssm学生管理系统 毕业设计 141543
  • .form文件_一篇文章学会文件上传
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .Net8 Blazor 尝鲜
  • .pop ----remove 删除
  • @Resource和@Autowired的区别
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • []T 还是 []*T, 这是一个问题