ADV-200 算法提高 求最大值

本文介绍了一种通过动态规划解决特定优化选择问题的方法。该问题要求从一系列有序整数对中选择一些对,使所选对的 ai+bi 和最大,同时确保 ai 和 bi 的和均为非负。文章详细解释了状态转移方程、如何处理负值情况及偏移量的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述
  给n个有序整数对ai bi,你需要选择一些整数对 使得所有你选定的数的ai+bi的和最大。并且要求你选定的数对的ai之和非负,bi之和非负。
输入格式
  输入的第一行为n,数对的个数
  以下n行每行两个整数 ai bi
输出格式
  输出你选定的数对的ai+bi之和
样例输入
5
-403 -625
-847 901
-624 -708
-293 413
886 709
样例输出
1715
数据规模和约定
  1<=n<=100
  -1000<=ai,bi<=1000
 

    dp[i][j],i表示前i个数对,j表示所采取的数对的ai之和,dp[i][j]表示对应的bi之和。
    首先考虑一个问题,题目要求的是ai之和非负,bi之和非负,还有一个隐藏的条件是,如果一个数对都不挑选的话,那么对应的结果应该是0。
    所以我们考虑在输入期间就把ai为负值,bi也为负值的数对全部去除,因为一旦用到他们肯定不会是最优解。
状态方程:dp[i][j]=max(dp[i-1][j-ai]+bi,dp[i][j]);  j-ai是为了得到当没有加入ai时对应的dp值,所以dp[i-1][j-ai]+bi就是加入ai得到的dp值。对某一个状态来说,dp[i][j]+j就是他们的ai与bi之和。
    将ai值和bi值偏移为正值之后的确就是一个很显然的背包问题。
    需要注意的是,这题的状态转移比普通的背包要严苛得多。

    在背包问题中,我们说在第i次选择时,当前状态dp[i][j]可以由两个状态转移而来,一个是dp[i][v-1],一个是dp[i-1][v-v[i]],但是在此题中只能是dp[i-1][j]和dp[i-1][j-a[i]]转移而来,直接承接上一行的值是因为,j表示的是ai之和,是限定死的。

    唯一可能的问题是,为什么明明有偏移量,最后只需要一个dp[ans][y+pe]+y即可得到答案。
    理由如下:实际上我们仅仅在

for(int o=1;o<=ans;o++)
{
       dp[o][a[o]+pe]=b[o];
}
这里初始化的时候加了偏移量,在此之后的状态转移过程中,并没有再加偏移量,回到状态dp的定义,dp[i][j]表示的是在前i个数对中选择,选择得到的数对的ai之和为j,状态中存入的量为对应的bi之和。

dp[i][j+pe],j+pe仅仅是为了避免加上负值的ai导致越界而制造的偏移罢了,所以j+dp[i][j+pe]就是最终解。

至于为什么最后的解落在dp[n][0+pe]~dp[n][pe+pe],想必已经很明显了吧,题目要求ai之和非负,若是在dp[n][0]~dp[n][pe],减去偏移量后,对应的ai之和是负值,因此无须考虑。

#include<iostream>
#define min 0x8f000000
using namespace std;
int n,a[105],b[105],dp[105][200005],pe=100000;//pe为偏移量   题目要求上限100个数,数值上下限为+ -1000,所以总区间长度为200000 
int main()
{ 
	int p,q,min1=min;
	cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		cin>>p>>q;
		if(p<0&&q<0)
		{
			continue;
		} 
		a[++ans]=p;
		b[ans]=q;
	}
	
	for(int j=1;j<=ans;j++)
	{
		for(int k=-pe;k<=pe;k++)
		{
			dp[j][k+pe]=min1;
		}
	}
	
	for(int o=1;o<=ans;o++)
	{
		dp[o][a[o]+pe]=b[o];
	}
	
	for(int u=2;u<=ans;u++)
	{
		for(int z=-pe;z<=pe;z++)
		{
			dp[u][z+pe]=max(dp[u-1][z+pe],dp[u][z+pe]);
			if(z+pe-a[u]<0||z+pe-a[u]>200000)//加上a[i]是否越界  下一步状态转移中要求有dp[u-1][z+pe-a[i]],故需要越界判断   实际上要求ai之和非负,bi之和非负在这个判断中得以体现,并且最后的取最优是从pe开始的,z-a[u]这一步是为了得到之前的状态,若产生越界错误,即从如果当前的状态是a[u]放入后得到的,那么他的前一个状态并不能存在,那么状态转移有问题。     
				continue; 
			dp[u][z+pe]=max(dp[u][z+pe],dp[u-1][z+pe-a[u]]+b[u]);
		}
	} 
	
	int temp=min;
	
	for(int y=0;y<=pe;y++)//也就是说在左端的值并没有进行考虑,在左端的值,就是ai之和为负值的情况 
	{
		temp=max(temp,(dp[ans][y+pe]>=0?dp[ans][y+pe]+y:min1));
	} 
	
	if(temp==min1)
	{
		cout<<"0";
	}
	else 
		cout<<temp;
	return 0;
}


<think>好的,我现在需要帮用户逐行解释一段HTML代码的功能和作用。用户希望每行都有注释,说明其作用。首先,我需要回忆HTML的基本结构和常见标签。然后,根据用户提供的引用,可能需要考虑一些特定的情况,比如iframe的动态写入或者JavaScript的外部引用。不过用户的问题主要集中在HTML代码的逐行注释,所以我应该先专注于HTML部分,如果有涉及JavaScript或CSS再考虑引用中的内容。 首先,我会假设用户提供的HTML代码可能包含常见的标签,比如<!DOCTYPE html>, <html>, <head>, <body>等。我需要确保每个标签都有解释,比如<!DOCTYPE html>声明文档类型,<html>是根元素等。接下来,可能会遇到<meta>标签,用于字符编码或视口设置,<title>定义标题,<link>引入CSS文件,<script>引入JavaScript文件。 如果用户提供的代码中有iframe,我需要引用引用[3]的内容,解释srcdoc属性及其兼容性问题。例如,动态创建iframe时使用srcdoc属性,但旧版浏览器不支持,可能需要polyfill。此外,如果涉及Dreamweaver编辑的问题,引用[2]提到外置JavaScript后不能在行为面板编辑,这可能影响注释内容,但用户的问题主要是HTML注释,所以可能暂时不需要深入。 引用[1]提到注释应尽量少,代码本身要易读,所以在添加注释时要简明扼要,只解释必要部分,避免冗余。例如,在<div>标签处说明其结构用途,而不是每个属性都详细说明,除非有特殊作用。 然后,我需要检查是否有条件判断,比如引用[4]中的coco数据集判断,可能在JavaScript部分,但用户的问题是关于HTML的,所以这部分可能不涉及,除非HTML中有相关的元素或属性。 接下来,我需要按照用户要求,逐行为代码添加注释,使用中文,并确保LaTeX格式正确,如果有数学表达式的话。不过HTML代码中通常不会有数学内容,所以可能不需要处理这点。但需要确保代码块格式正确,注释清晰。 最后,生成相关问题,可能涉及HTML结构优化、标签语义化、SEO优化、CSS/JS引入方式、兼容性问题处理等,结合用户提供的引用内容,比如iframe的动态写入、Dreamweaver编辑限制等。 现在,假设用户提供的HTML代码可能如下(因为用户没有提供具体代码,我需要假设一个常见例子): <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>示例页面</title> <link rel="stylesheet" href="styles.css"> </head> <body> <header> <h1>欢迎来到我的网站</h1> </header> <main> <p>这是一个段落。</p> <iframe srcdoc="<p>动态内容</p>"></iframe> </main> <script src="script.js"></script> </body> </html> 针对这样的代码,我需要逐行注释: 1. <!DOCTYPE html>:声明文档类型为HTML5。 2. <html lang="zh-CN">:根元素,设置语言为中文。 3. <head>:头部,包含元数据和资源链接。 4. <meta charset="UTF-8">:设置字符编码为UTF-8。 5. <meta name="viewport" ...>:响应式视口设置。 6. <title>:页面标题。 7. <link ...>:引入外部CSS文件。 8. </head>:头部结束。 9. <body>:主体内容开始。 10. <header>:页眉部分。 11. <h1>:主标题。 12. </header>:页眉结束。 13. <main>:主体内容容器。 14. <p>:段落。 15. <iframe ...>:内嵌框架,使用srcdoc动态写入内容(引用[3])。 16. </main>:主体结束。 17. <script ...>:引入外部JavaScript文件。 18. </body>:主体结束。 19. </html>:HTML结束。 生成的问题可能涉及视口设置的作用、iframe的替代方案、语义化标签的好处、外部资源引入方式等。</think>以下是HTML代码的逐行注释及功能说明: ```html <!DOCTYPE html> <!-- 声明文档类型为HTML5,确保浏览器以标准模式解析 --> <html lang="zh-CN"> <!-- 根元素,lang属性指定文档语言为简体中文 --> <head> <!-- 文档头部,包含元数据和资源链接 --> <meta charset="UTF-8"> <!-- 指定字符编码为UTF-8,支持多语言显示 --> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 响应式设计设置,适配移动端 --> <title>示例页面</title> <!-- 定义浏览器标签页标题 --> <link rel="stylesheet" href="styles.css"> <!-- 引入外部CSS样式表 --> </head> <body> <!-- 文档主体内容 --> <header> <!-- 语义化标签,表示页面页眉 --> <h1>欢迎来到我的网站</h1> <!-- 一级标题 --> </header> <main> <!-- 主体内容容器 --> <p>这是一个段落。</p> <!-- 段落文本 --> <iframe srcdoc="<p>动态内容</p>"></iframe> <!-- 内嵌框架,使用srcdoc直接写入HTML内容[^3] --> </main> <script src="script.js"></script> <!-- 引入外部JavaScript文件 --> </body> </html> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风间琉璃c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值