首页 > 其他分享 >P1941 做题笔记

P1941 做题笔记

时间:2024-07-25 22:08:48浏览次数:11  
标签:pii min int kN 笔记 using P1941 first

题目

经典多重背包

设 \(f_{i, j}\) 表示当前在第 i 个位置,高度为 j 的最小代价,那么可以简单写出转移式:

\[f_{i, j} = \min(f_{i - 1, j + y}, f_{i - 1, j - x}) \]

并且要注意一些细节:由于是多重背包,注意从低位往高位枚举,当 \(j = m\) 时,\(f_{i, j}\) 可以从 \([m - y, m)\) 转移过来。现在考虑有管道挡住的情况,显然有管道的地方永远转移不到其它地方,所以直接令这些地方为一个极大值即可。

注意到 \(f_{i, j}\) 只和 \(f_{i - 1, ?}\) 有关,所以可以用滚动数组省掉一维(然而这道题目不用省空间,\(O(nm)\) 的空间是可以过去的)

Code
#include <algorithm>
#include <iostream>

using namespace std;
using pii = pair<int, int>;

const int kV = 1e3 + 1, kN = 1e4 + 1;

int n, m, k, ans = 1e9, f[kV], g[kN];
pii a[kN];
struct AC {
  int x, l, h;

  bool operator<(const AC x) const {
    return this->x < x.x;
  }
} c[kN];

int C() {
  for (int i = 1; i <= m; i++) {
    if (f[i] != 1e9) {
      return 0;
    }
  }
  return 1;
}

int main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> m >> k;
  for (int i = 0; i < n; i++) {
    cin >> a[i].first >> a[i].second;
  }
  for (int i = 1; i <= k; i++) {
    cin >> c[i].x >> c[i].l >> c[i].h;
  }
  sort(c + 1, c + k + 1);
  for (int i = 1, k = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (j + a[i - 1].second <= m) {
        f[j] = g[j + a[i - 1].second];
      } else {
        f[j] = 1e9;
      }
      if (j - a[i - 1].first > 0) {
        f[j] = min(f[j], g[j - a[i - 1].first] + 1);
        g[j] = min(g[j], g[j - a[i - 1].first] + 1);
      }
    }
    for (int j = m - a[i - 1].first; j <= m; j++) {
      f[m] = min(f[m], g[j] + 1);
    }
    if (i == c[k].x) {
      for (int j = 1; j <= c[k].l; j++) {
        f[j] = 1e9;
      }
      for (int j = c[k].h; j <= m; j++) {
        f[j] = 1e9;
      }
      if (C()) {
        cout << "0\n" << k - 1 << '\n';
        return 0;
      }
      k++;
    }
    for (int j = 1; j <= m; j++) {
      g[j] = f[j];
    }
  }
  for (int i = 1; i <= m; i++) {
    ans = min(ans, f[i]);
  }
  cout << "1\n" << ans;
  return 0;
}

标签:pii,min,int,kN,笔记,using,P1941,first
From: https://www.cnblogs.com/SuperSupper/p/18324174

相关文章

  • BSGS 学习笔记
    BSGS拔山盖世、北上广深……实际上叫大步小步,用于解决高次同余方程,形如:\[a^x\equivb\pmodp\]求\(x\)。设\(x=i\timest-j\),有:\[a^{i\timest-j}\equivb\pmodp\]\[a^{i\timest}\equivb\timesa^j\pmodp\]预处理每个\(j\),枚举\(i\)处理,\(t\)取\(\sqrtn\)最......
  • 7月24日JavaSE学习笔记
    序列化版本控制序列化:将内存对象转换成序列(流)的过程反序列化:将对象序列读入程序,转换成对象的方式;反序列化的对象是一个新的对象。serialVersionUID是一个类的序列化版本号privatestaticfinallongserialVersionUID=1L;//版本号如果序列化版本号没有定义,JDK会自动......
  • 7月25日JavaSE学习笔记
    线程的生命周期中,等待是主动的,阻塞是被动的锁对象创建锁对象,锁对象同一时间只允许一个线程进入//创建锁对象Locklock=newReentrantLock(true);//创建可重入锁可重入锁:在嵌套代码块中,锁对象一样就可以直接进入执行公平锁:保证线程获取锁的顺序与线程请求锁的顺序......
  • 文本笔记
    1.画盒子大盒子dvi,小盒子p 2.类选择器. id选择器#文本属性::text-align居中属性tetx-aligin本质是控制内容剧中的,属性设置给内容设置文本属性:text-indent:2em;font-size:文本大小30px;文本修饰线:text-decoration:none;去掉线underlines下划线line-throug......
  • Java笔记day10
    一,不同方式创建多个线程并打印(1)定义了一个RunA实现Runnable接口,定义list存储数据,并重写了run方法 ,在run方法里定义循环向list中添加数据a;在main方法中创建a,b两个线程并引用该run方法,输出run对象的list和长度publicstaticvoidmainB(String[]args){RunAru......
  • 前段学习笔记
    <form>表单一般包含按钮<input>标签使用:登录,注册,搜索typetest文本,password密码,rodio单选,checkbox多选,file文件上传表格<table用来展示数据>table代表盒子,tr是行,th是表头单元格,td是内容单元格table无边框,加border属性添加边框。th有加粗和居中的效果普通在td里面......
  • 深度学习与图像识别学习笔记day1
    文件不可以与现有的包重名哦1、Theano(旧)一个python库,可用于定义、优化与计算数学表达式,特别是多维数组(numpy.ndarray),可以理解为一个数学表达式的编译器:用符号式语言定义程序员所需的结果,并可以高效的运行与GPU与CPU上。2、Tensorflow(新)基于计算图实现自动微分系统,tensorflow......
  • 【笔记】计算几何
    %经典问题%.1平面最近点对分治是容易想到的。主要是合并,如果我们要更优,那么一定比左右两个子区间更优,所以我们初步框定了每个点最多能产生贡献的点集,而这个点集内部的两个点,如果同属一个子区间,那么之间的距离必定天然满足大于等于该子区间的最优答案,所以实际上我们框定范围内......
  • C++学习笔记-operator关键字:重载与自定义操作符
    在C++编程中,operator关键字扮演着极其重要且独特的角色。它允许开发者为内置类型或自定义类型重载或定义新的操作符行为。这一特性极大地增强了C++的表达能力,使得代码更加直观、易于理解和维护。本文将深入探讨C++中operator关键字的使用,包括操作符重载和自定义操作符的基本......
  • Unity中有关Animation的一点笔记
    也许更好的阅读体验AnimationUnity中Animation类并不是直接记载了和播放动画有关的信息,可以简单理解Animation为一个动画播放器,播放的具体内容就像卡带一样,当我们有了卡带后我们可以播放动画。对应的则是编辑器中的组件所以Animation里有一些和播放器的函数:函数名函数功......