首页 > 其他分享 >DP总结

DP总结

时间:2024-02-17 17:12:12浏览次数:31  
标签:总结 件物品 int 枚举 体积 maxn DP

  • DP(动态规划)简介
    动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
    由于动态规划并不是某种具体的算法,而是一种解决特定问题的方法,因此它会出现在各式各样的数据结构中,与之相关的题目种类也更为繁杂。

  • DP基础

    1.必要前提
    需要满足三个条件:最优子结构,无后效性和子问题重叠。

    2.基本思路

    1. 将原问题划分为若干 阶段,每个阶段对应若干个子问题,提取这些子问题的特征(称之为 状态);
    2. 寻找每一个状态的可能 决策,或者说是各状态间的相互转移方式(用数学的语言描述就是 状态转移方程)。
    3. 按顺序求解每一个阶段的问题。
  • 各种DP

    1. 背包DP
      1. 01背包!
        • 朴素版

          点击查看代码
          #include <bits/stdc++.h>
          using namespace std;
          const int maxn = 1010;
          //f[i][j]表示前i个物品,体积不超过j时的最大价值
          //不选第i个物品时,f[i][j] = f[i-1][j]
          //选第i个物品时,f[i][j] = f[i-1][j-v[i]]+w[i],保证j>=v[i] 
          int f[maxn][maxn] = {};	//默认全为0,这样后面就不需要再初始化
          int n = 0, m = 0;	//n件物品,m为背包总容量
          int v[maxn] = {}, w[maxn] = {};	//v表示第i件物品体积,w为第i件物品价值
          int main()
          {	
          	scanf("%d%d", &n, &m);
          	for(int i=1; i<=n; i++) scanf("%d%d", &v[i], &w[i]); 
          	for(int i=1; i<=n; i++)
          	{
          		for(int j=0; j<=m; j++)
          		{
          			f[i][j] = f[i-1][j];
          			if(j>=v[i]) f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);
          		}
          	}
          	printf("%d", f[n][m]);
          	return 0;
          }
          
          
        • 滚动数组优化版 因为每次的动态转移只与i-1层(前i-1个物品)的dp值相关 所以可用二维数组模拟滚动数组以减少内存

        • 终极版
          我们发现物品枚举顺序跟结果无关,枚举体积时先枚举体积大的还是小的也不影响最后结果,如果我们枚举体积的时倒序枚举,那在第二层循环中(j)f[j]之前的位置(f[1]~f[j-1])都是在选前i-1件物品是的无后效性的dp值,这样我们就可以省去一维数组,我们用f[j]表示处理当前第i件物品时体积为j的最大价值,
          递推公式:f[j]=max(f[j],f[j-v[i]]+w[i])。表达式右边的f[j],f[j-v[i]]表示处理完上个物品之后的结果,由于倒序处理处理体积j的时候f[j], f[j-v[i]]还保留着上一行的状态

          点击查看代码
          #include <bits/stdc++.h>
          using namespace std;
          const int maxn = 1010;
          int f[maxn] = {};	//默认全为0,这样后面就不需要再初始化
          int n = 0, m = 0;	//n件物品,m为背包总容量
          int v[maxn] = {}, w[maxn] = {};	//v表示第i件物品体积,w为第i件物品价值
          int main()
          {	
          	scanf("%d%d", &n, &m);
          	for(int i=1; i<=n; i++) scanf("%d%d", &v[i], &w[i]); 
          	for(int i=1; i<=n; i++)
          	{
          		for(int j=m; j>=v[i]; j--)
          		{ 
          			f[j] = max(f[j], f[j-v[i]] + w[i]);
          		}
          	}
          	printf("%d", f[m]);
          	return 0;
          }
          

标签:总结,件物品,int,枚举,体积,maxn,DP
From: https://www.cnblogs.com/CTHoi/p/18018139

相关文章

  • 树形dp
    树形dp模型:给定一颗有n个节点的树,任选一个节点为根节点,从而定义出每个节点的深度和每棵子树的根。基本思路:1.建树2.列出动态转移方程典型例题:没有上司的舞会#include<bits/stdc++.h>usingnamespacestd;intn,l,k,ans;vector<int>son[6600];intf[6600][2],v[6600],r......
  • 区间DP
    先看一下模板点击查看代码//f[i][j]表示从i到j区间的值for(intlen=2;len<=n;len++)//len表示区间长度{ for(inti=1;i+len-1<=n;i++)//关系一般为2<=i<=k<j<=n { intj=i+len-1;//j的求值,开始点+区间长度-1 for(intk=i;k<j;k++) { f[i][j]=min/max(状态转移......
  • 坐标DP
    坐标DP相较来说会比较简单。直接上例题1.坐标遍历问题传纸条点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=120;intm,n;intg[N][N],f[N][N][N];intans;intmain(){ cin>>n>>m; for(inti=1;i<=n;i++) { for(intj=1;j<=m;j++) { ......
  • 关于动态规划(Dynamic Programming)的若干思考 ------ [2.线性dp]
    线性dp的两个经典题目:最长上升子序列(LIS)and最长公共子序列(LCS)1.LIS核心代码#include<bits/stdc++.h>usingnamespacestd;constintmaxn=2024;intcnt=0,ans=1;intf[maxn],a[maxn],c[maxn];voidout(intx){ if(x==0)return; out(c[x]); cout<<a[x]<<......
  • 线性dp
    基本应用:最长上升子序列:题目描述设有由n个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)且b(i)<>b(j)(i<>j),若存在i1<i2<i3<…<ie且有b(i1)<b(i2)<…<b(ie)则称为长度为e的不下降序列。程序要求,当原数列出之后,求出最长的上升序列。例如13,7,9,16,38,24,37,18,44,19,21,22,63......
  • dp总结(背包,线性,区间,坐标,树形)
    背包dp0/1背包这种背包会提供可选的物品,背包的容积以及每件物品的价值,并且在选择物品是每件物品只有选一件或不选两种状态。例题输入4512243445输出8二维解法代码//状态转移方程为:f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i])#include"bits/stdc++.h"using......
  • 坐标dp
    坐标dp典型例题:传纸条题目描述小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传......
  • 线性DP
    这篇主要涉及线性DP。先介绍给模型,求最长上升子序列。点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintN=1020;intn;intf[N],ans,a[N];intpre[N],te;voidoutput(intx){ if(x==0) { return; } output(pre[x]); cout<<a[x]<<"";......
  • 区间dp
    区间dp区间dp属于线性dp的一种,以“区间长度”作为dp的“阶段”,用两个坐标(区间的左、右端点)描述每个维度。区间dp中,一个状态往往由若干个比它更小且包含于它的区间所代表的阶段转移而来,所以区间dp的决策往往就是划分dp的方法。典型例题:石子合并for(inti=1;i<=n;i++)f[i][i]=......
  • 五大基础dp
    动规条件•最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。•无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。•有重叠子问题:即子问题之......