首页 > 其他分享 >背包DP

背包DP

时间:2023-04-15 11:55:34浏览次数:32  
标签:index 背包 ++ int DP -- dp

背包DP

二进制分组优化

考虑优化。我们仍考虑把多重背包转化成 0-1 背包模型来求解。

预处理物品数量是2的次方。且要覆盖物品数量的点。即2 n次方+1到k

index = 0;
for (int i = 1; i <= m; i++) {
  int c = 1, p, h, k;
  cin >> p >> h >> k;
  while (k > c) {
    k -= c;
    list[++index].w = c * p;
    list[index].v = c * h;
    c *= 2;
  }
  list[++index].w = p * k;
  list[index].v = h * k;
}

单调队列优化背包

求区间为m中的最小值

t=1;
	for (i=1;i<=n;i++)
	{
		if ((b[t]<i-m+1)and(t<=w))
			t++;
		while ((t<=w)and(a[b[w]]>=a[i]))
			w--;
		w++;
		b[w]=i;
		if (i>=m)
			cout<<a[b[t]]<<' ';
	}

单调队列求连续子序列最大和

子序列最大长度为m

for (i=1;i<=n;i++)
	{
		cin>>x;
		a[i]=a[i-1]+x;
	}
	ma=a[1];
	for (i=1;i<=n;i++)
	{
		if ((b[t]<i-m+1)and(t<=w))
			t++;
		ma=max(ma,a[i]-a[b[t]]);
		while ((t<=w)and(a[b[w]]>=a[i]))
			w--;
		w++;
		b[w]=i;
	}
	cout<<ma<<'\n';

单调队列优化多重背包

	cin>>n>>m;
	for (i=1;i<=n;i++)
	{
		cin>>v>>z>>k;             //价值 重量 数量
		for (j=0;j<=z-1;j++)
		{
			t=0;w=0;
			o=(m-j)/z;
			for (l=0;l<=o;l++)
			{
				while ((t<w)and(f[j+l*z]-l*v>=c[w-1]))
					w--;
				b[w]=l;
				c[w]=f[j+l*z]-l*v;
				w++;
				while ((t<w)and(b[t]<l-k))
					t++;
				f[j+l*z]=max(f[j+l*z],c[t]+l*v);
			}
		}
	}
	cout<<f[m];

有依赖的背包

金明的预算方案 洛谷1064

#include<bits/stdc++.h>
using namespace std;
int n,m,i,x,q,t,k,j,l,z,vv,pp,f[400005],v[40005],p[40005],a[40005];
vector<int>b[40005];
int main()
{
	cin>>m>>n;
	for (i=1;i<=n;i++)
	{
		cin>>v[i]>>p[i]>>x;
		p[i]=p[i]*v[i];
		if (x==0)
			a[++k]=i;
		else
			b[x].push_back(i);
	}
	for (i=1;i<=k;i++)
	{
		q=a[i];
		t=b[q].size();
		for (l=m;l>=v[q];l--)
		{
			for (j=0;j<=(1<<t)-1;j++)
			{
				vv=v[q];pp=p[q];
				for (z=0;z<b[q].size();z++)
					if ((1<<z)&j)
					{
						vv=vv+v[b[q][z]];
						pp=pp+p[b[q][z]];
					}
				if (l>=vv)
					f[l]=max(f[l],f[l-vv]+pp);
			}
		}
	}
	cout<<f[m]<<'\n';
}

01背包的第K优解

memset(dp, 0, sizeof(dp));
int i, j, p, x, y, z;
scanf("%d%d%d", &n, &m, &K);
for (i = 0; i < n; i++) scanf("%d", &w[i]);
for (i = 0; i < n; i++) scanf("%d", &c[i]);
for (i = 0; i < n; i++) {
  for (j = m; j >= c[i]; j--) {
    for (p = 1; p <= K; p++) {
      a[p] = dp[j - c[i]][p] + w[i];
      b[p] = dp[j][p];
    }
    a[p] = b[p] = -1;
    x = y = z = 1;
    while (z <= K && (a[x] != -1 || b[y] != -1)) {
      if (a[x] > b[y])
        dp[j][z] = a[x++];
      else
        dp[j][z] = b[y++];
      if (dp[j][z] != dp[j][z - 1]) z++;          //策略不同但权值相同的看作重复的就加这句
    }
  }
}
printf("%d\n", dp[m][K]);

多人背包 洛谷1858

#include<bits/stdc++.h>
using namespace std;
int k,n,m,i,j,p,x,y,s,t,w,z,f[5005][55],a[55],b[55];
int main()
{
	cin>>k>>m>>n;
	for (i=0;i<=m;i++)
		for (j=1;j<=k;j++)
			f[i][j]=-1000000000;
	f[0][1]=0;
	for (i=1;i<=n;i++)
	{
		cin>>x>>y;
		for (j=m;j>=x;j--)
		{
			for (p=1;p<=k;p++)
			{
				a[p]=f[j-x][p]+y;
				b[p]=f[j][p];
			}
			t=w=z=1;
			while (((t<=k)or(w<=k))and(z<=k))
			{
				if (a[t]>b[w])
					f[j][z]=a[t++];
				else f[j][z]=b[w++];
				z++;
			}
		}
	}
	for (i=1;i<=k;i++)
		s+=f[m][i];
	cout<<s<<'\n';
}

标签:index,背包,++,int,DP,--,dp
From: https://www.cnblogs.com/ShadowAA/p/17320812.html

相关文章

  • PyQt5 软件在 macOS HiDPI 模式下出现字体模糊的问题
    ​ Retina屏幕是苹果公司在2010年在 WWDC上发布的一种高密度像素的屏幕。HiDPI是一种渲染技术,它可以让Retina屏幕上的图像更加清晰。HiDPI技术会将图像渲染成两倍于原始分辨率的大小,然后再将其缩小到原始分辨率的大小,这样就可以让图像更加清晰。PyQt5编写的软件在Wi......
  • 计算机网络 传输层协议TCP和UDP
    目录一、传输层协议二、tcp协议介绍三、tcp报文格式四、tcp三次握手五、tcp四次挥手六、udp协议介绍七、常见协议和端口八、有限状态机  一、传输层协议传输层协议主要是TCP和UDP协议主要作用1.分段和重组2.会话多路复用 二、tcp协议......
  • 神策数据入选 IDC 中国客户数据平台 CDP 市场规模及厂商份额报告
    近日,IDC首发中国客户数据平台CDP市场规模及厂商份额报告,明确了CDP产品的功能和使用方式,以便减少购买者的困惑。IDC市场份额报告调研的厂商包括神策数据在内的15家企业,报告显示,市场前5家公司营业额几乎占整个市场的二分之一(47.1%)。报告中,IDC将CDP产品的主要功能分为......
  • 解决 dpkg 安装出错后的 Sub-process /usr/bin/dpkg returned an error code (1) 错误
    在使用dpkg-i安装.deb软件包的过程中,会出现安装失败的可能。之后无论用sudoaptinstall-forsudaptautoremove等常见的修复命令都是无效的。网络上很多解决方案都直接给出需要运行的命令,不分析原因也不说明理由。我从来不尝试这样的解决方案,除非我自己知道或是只能死马......
  • 【DP】【分治】LeetCode 53. 最大子数组和
    题目链接[https://leetcode.cn/problems/maximum-subarray/description/](53.最大子数组和"https://leetcode.cn/problems/maximum-subarray/description/")思路分析动态规划题目的时候只需要考虑最后一个阶段,因为所有的阶段转化都是相同的,考虑最后一个阶段容易发现规律在数......
  • Codeforces Round #286 (Div. 2) C题 Mr. Kitayuta, the Treasure Hunter (DFS+记忆化D
    题目地址:http://codeforces.com/contest/505/problem/C从d点开始,每个点都有三个方向,形成了一棵树,那么就从跟结点开始进行dfs查找,dp数组记录当前的点和长度,当这两个条件相同的时候,显然,后面的子树是完全相同的,于是用记忆化来优化。代码如下:#include<iostream>#include<string.h>#......
  • HDU 2089 不要62 (数位DP)
    简单的数位DP。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>#include<stdio.h>usingnamespacestd;#d......
  • HDU 4628 Pieces (状压DP)
    题目地址:HDU4628这题没想到怎么快速枚举子状态。。。看了题解才知道的。用for(state=i;state>0;state=(state-1)&i)就可以了。这题的具体做法是先预处理出所有的状态是不是回文串,然后就是普通的DP了。代码如下:#include<iostream>#include<string.h>#include<math.h>......
  • Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome (DP+字典树)
    题目地址:传送门先用dp求出所有的符合要求的半回文串,标记出来。然后构造字典树。然后再dfs一遍求出所有节点的子树和,最后搜一遍就能找出第k个来了。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib......
  • 背包问题
    01背包问题题目有一个背包的容积为\(m\),有\(n\)个物品,每个物品的体积为\(w\),权重为\(v\),每个物品只能取\(1\)次放入背包中,背包所有物品权重和最大是多少?求值创建一个状态矩阵\(dp\),横坐标\(i\)表示物品编号,纵坐标\(j\)表示背包容量。\(dp[i][j]\)表示在已用背包容量为\(j\)的......