首页 > 其他分享 >P8392 [BalticOI 2022 Day1] Uplifting Excursion(特殊背包问题)

P8392 [BalticOI 2022 Day1] Uplifting Excursion(特殊背包问题)

时间:2024-10-07 19:23:52浏览次数:9  
标签:贪心 背包 Uplifting Day1 体积 2022 物品 include define

题意简述

有 \(2m+1\) 种物品,体积分别为 \(-m\sim m\),每种物品有 \(a_i\) 个。

你需要选出尽可能多数量的物品,使得物品体积和为 \(l\)。

\(m\le 300,a_i,|l|\le 10^{18}\)

分析

此题属于“背包容量极大,物品体积极小”的特殊背包问题。

考虑背包问题的经典错误贪心:按照性价比降序排序取。错误原因是,这个方案可能会浪费一些背包容量,使得我们可以通过扔出一些物品再加入一些别的物品充分利用背包容量,从而最大化价值。

但此题容量极大,也就是说,背包容量“不怕浪费”!我们考虑前面按照性价比贪心取东西直到背包放不下了。但此时我们遇到了相同的问题:我们还是浪费了一些背包容量。

考虑在贪心出来的结果上进行常规背包 DP。将取过的物品的价值和体积取反,表示撤销该物品,没取过的物品不变。设 \(f_{i}\) 表示在贪心的基础上选取的物品体积和为 \(i\) 的最大价值,注意 \(i\) 在此定义下可以为负。

发掘性质:

  • 令贪心后选的物品体积总和为 \(L\),则 \(L\in (l-m,m]\),显然,否则贪心不成立。
  • 存在一种最优方案使得每次取完物品/反悔物品后物品的总体积在 \([l-m,l+m]\),因为最终的总体积落在 \(l\),所以我们可以在 \(l'<l\) 时加入物品,在 \(l'>l\) 时加入反悔物品,通过调整使其满足条件。
  • 在贪心基础上我们会选择至多 \(2m\) 个物品,因为根据上一条性质,每次选完物品后的体积落在 \([l-m,l+m]\) 内,而一定不会存在某个体积会被重复到达且更优的情况(否则中间这段就相当于不消耗任何体积而白嫖了更多的价值,此时我们在贪心的基础上用这种方案白嫖会使得贪心方案更优,使贪心不成立)。而区间内一共就 \(2m\) 种体积。
  • 根据第三条性质,我们直接把背包容量开到 \([-m^2,m^2]\) 做常规 DP 即可,视多重背包的实现复杂度三方或三方对数。
  • 代码三方对数。
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<unordered_map>
#include<vector>
#include<queue>
#include<bitset>
#include<set>
#include<ctime>
#include<random>
#include<cassert>
#define x1 xx1
#define y1 yy1
#define IOS ios::sync_with_stdio(false)
#define ITIE cin.tie(0);
#define OTIE cout.tie(0);
#define PY puts("Yes")
#define PN puts("No")
#define PW puts("impossible")
#define P__ puts("")
#define PU puts("--------------------")
#define P0 puts("0")
#define popc __builtin_popcount
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define gc getchar
#define pc putchar
#define pb emplace_back
#define rep(a,b,c) for(int a=(b);a<=(c);++a)
#define per(a,b,c) for(int a=(b);a>=(c);--a)
#define reprange(a,b,c,d) for(int a=(b);a<=(c);a+=d)
#define perrange(a,b,c,d) for(int a=(b);a>=(c);a-=d)
#define graph(i,j,k,l) for(int i=k[j];i;i=l[i].nxt)
#define lowbit(x) (x&-x)
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define mem(x,y) memset(x,y,sizeof x)
//#define double long double
#define int long long
//#define int __int128
using namespace std;
typedef long long i64;
bool greating(int x,int y){return x>y;}
bool greatingll(long long x,long long y){return x>y;}
inline int rd(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*f;
}
inline void write(int x,char ch='\0'){
    if(x<0){x=-x;putchar('-');}
    int y=0;char z[40];
    while(x||!y){z[y++]=x%10+48;x/=10;}
    while(y--)putchar(z[y]);if(ch!='\0')putchar(ch);
}
bool Mbg;
const int maxn=305,maxm=1e6+5,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
int n,m,l;
int a[maxn],b[maxn];
int c[maxn],d[maxn];
int f[maxm];
void ins(int c,int v,int w){
	if(v>0){
		for(int j=1;j<=c;c-=j,j<<=1){
			per(i,2*m,j*v)f[i]=max(f[i],f[i-j*v]+j*w);
		}
		if(c){
			per(i,2*m,c*v)f[i]=max(f[i],f[i-c*v]+c*w);
		}
	}else{
		v=-v;
		for(int j=1;j<=c;c-=j,j<<=1){
			rep(i,0,2*m-j*v)f[i]=max(f[i],f[i+j*v]+j*w);
		}
		if(c){
			rep(i,0,2*m-c*v)f[i]=max(f[i],f[i+c*v]+c*w);
		}
	}
}
void solve_the_problem(){
    n=rd(),m=n*n,l=rd();
    int res=0;
    per(i,n,1)a[i]=rd(),l+=a[i]*i,res+=a[i];
    res+=rd();
    rep(i,1,n)b[i]=rd();
    if(l<0)return (void)PW;
    rep(i,1,n){
    	if(l>=b[i]*i)l-=b[i]*i,res+=b[i],d[i]=b[i];
    	else{d[i]=l/i,res+=d[i],l-=d[i]*i;break;};
	}
	per(i,n,1){
		if(l>=a[i]*i)l-=a[i]*i,res-=a[i],c[i]=a[i];
		else{c[i]=l/i,res-=c[i],l-=c[i]*i;break;}
	}
	mem(f,0xc0);
	f[m]=res;
	rep(i,1,n){
		ins(c[i],-i,1);
		ins(a[i]-c[i],i,-1);
		ins(d[i],-i,-1);
		ins(b[i]-d[i],i,1);
	}
	if(l>m||f[l+m]<0)PW; 
	else write(f[l+m]);
}
bool Med;
signed main(){
//	freopen(".in","r",stdin);freopen(".out","w",stdout);
//	fprintf(stderr,"%.3lfMB\n",(&Mbg-&Med)/1048576.0);
    int _=1;while(_--)solve_the_problem();
}
/*

*/

标签:贪心,背包,Uplifting,Day1,体积,2022,物品,include,define
From: https://www.cnblogs.com/dcytrl/p/18448384

相关文章

  • 雅礼国庆集训 day1 T2 折射
    题面题面下载算法转化题意说白了就是给了你一堆点,让你数这种折线有多少个(严格向下走,并且横坐标之间的差越来越小)看着像一种在y轴方向排序的dp但是由于是折线,所以需要加一维来判断转向dp设计状态设计\(dp_{i,0/1}\)表示第i个点,是向左下还是右上状态转移......
  • 20222315 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容1.掌握反汇编与十六进制编程器2.能正确修改机器指令改变程序执行流程3.能正确构造payload进行bof攻击2.实验过程1.直接修改程序机器指令,改变程序执行流程将pwn1文件下载至kali中并将pwn1文件改名为pwn20222315,并将其内容复制到pwn2反汇编文件objdump-dpwn2022231......
  • Day11-Scanner
    Day11-ScannerScanner介绍Scanner对象:之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。基本语法:Scanners=newScanner......
  • day1
    day1雷暴(storm)题目要求计算覆盖所有相同颜色格子的最小正方形的面积。#include<bits/stdc++.h>usingnamespacestd;intn,m,k;inta[1005][1005];structnode{ intx,y;}f[100005],g[100005];intmain(){ freopen("storm.in","r",stdin); freopen(......
  • 雅礼国庆集训 day1 T1 养花
    题面题目下载算法考虑当\(k\)确定的时候如何求答案,显然对于所有形如\([ak,(a+1)k)\)的值域区间,最大值一定是最优的似乎怎么都是\(O(n^2)\)的算法观察到\(a_i\)的值域比较小,所以考虑桶显然对于一段区间\([L,R]\)我们可以推出其\(modk\)的最大值方法......
  • day1
    day1雷暴(storm)题目要求计算覆盖所有相同颜色格子的最小正方形的面积。#include<bits/stdc++.h>usingnamespacestd;intn,m,k;inta[1005][1005];structnode{ intx,y;}f[100005],g[100005];intmain(){ freopen("storm.in","r",stdin); freopen(......
  • 20222301 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    一、实验目的本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个......
  • 20222427 2024-2025-1 《网络与系统攻防技术》实验一实验报告
    1.实验内容(1)本周学习内容1.学习缓冲区溢出的基本原理。2.重温栈与堆的概念以及执行流程。3.逐步熟悉Linux系统对文件的处理流程,掌握基础的汇编与反汇编语言。(2)本周实验任务1.手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。2.利用foo函数的Bof漏洞,构造一个攻......
  • 使用VS2022 Performance Profiler进行Native内存分析
    注:勾选MemoryUsage进行Native内存抓取 不带pdb要进行Native内存抓取点击Start按钮开始进行内存分析 点击“StopCollection”按钮,来结束Profile。 注:如果报如下错误:Failedtoloadmemoryusageview: System.NullReferenceException,需要将VS2022升级到最新或使用VS......
  • Day10-JavaDoc
    Day10-JavaDocJavaDoc介绍JavaDoc:javadoc命令是用来生成自己API文档的。javadoc是一个工具,它可以读取源代码中的文档注释,并将其转换为格式规范的API文档。javadoc通过解析文档注释中的特定标记,如@author、@version、@since、@param、@return、@throws等,来提取关键信......