首页 > 其他分享 >make N

make N

时间:2023-02-02 00:35:01浏览次数:35  
标签:lfloor make rfloor 性价比 lld% 操作 ll

DP不能干的事情,我贪心+特判干掉了!

前言

说来话长,那天我们拿到这张《杂题选讲》,指着看起来非常easy的T2讨论起来。

XXX:一看就是个背包变式。

XXX:肯定是贪心。

XX:确实像个背包,但物品少貌似能贪心?

然后放学回家,LQ上网搜素一波:哇!atcoder水题!水它!

题意

单子上写得明明白白

算了还是当回搬运工

初始化 \(P=0\),给定 \(N,A,B,X,Y,Z\),可以执行三种操作任意次:

  • 花费 \(X\) 元将 \(P+1\);

  • 花费 \(Y\) 元将 \(P+A\);

  • 花费 \(Z\) 元将 \(P+B\)。

求 \(P=N\) 的最小花费。

\(1 \le N,A,B,X,Y,Z \le 10^9\)

注意:有多组数据。

思路

看到范围果断干掉DP,考虑一下基于性价比的贪心思想。

首先发现,操作1可以用于填充另两个操作不能填满的部分。

同时可以进行一些特判:

  • 若操作1的性价比比其他都高,则用操作1填满;

  • 若操作1的性价比高于一项而低于另一项,不妨设高于操作2,低于操作3,则可以填充完操作2后用操作1补全。

完成特判后,我们只需要着手于一种情况:操作1的性价比最劣,即不能不用时才能用。

那么现在面临的问题就是:合理选择操作2与操作3的次数,使费用最少。

不妨暴力一点,直接枚举。真够bf的

现在操作2的上限次数为 \(\lfloor \frac{N}{A} \rfloor\),操作3的上限次数为 \(\lfloor \frac{N}{B} \rfloor\),无论选择哪项进行枚举,都可以卡到单次 \(O(N)\),显然不能承受。

考虑死不悔改。如果我们默认操作2的性价比更优,则可以发现操作3的上限次数会被限制在 \(A-1\),即 \(N \bmod A\) 的级别:若超出这个限制的操作,一定能被性价比更优的操作2所取代。

此时选择级别较小的一项枚举,就不会超时了,单次时间复杂度为 \(O(\sqrt N)\)。

为啥呢?

因为官方题解也是这么干的

好吧,我们来试着卡一下这个做法:

  1. 卡 \(\lfloor \frac{N}{A} \rfloor\) ,此时我们要卡他,需要把 \(A\) 干到 \(1\),那么 \(A-1\) 就跑得飞快。

  2. 卡 \(A-1\),此时需要把 \(A\) 整到 \(N\),那么 \(\lfloor \frac{N}{A} \rfloor\) 就卡不动了。

  3. 于是为了一个平衡,我们把 \(A\) 设为 \(\sqrt N\),那么两边都没法卡,而测试数据的数量在 \(100\) 以内,根本卡不动。

综上,我们就得到了这个好写又快的做法。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=0x7fffffffffffffff;
int N;
ll A,B,X,Y,Z;
inline ll solve(){
	if(Y*B>Z*A) swap(Y,Z),swap(A,B);
	int a=N/A,b=A-1;
	if(X*A<=Y) return N*X;
	if(X*B<=Z) return a*Y+N%A*X;
	ll ret=INF;
	if(a<=b){
		for(int i=0;i<=a;i++){
			int n=N-i*A;
			ret=min(ret,i*Y+n/B*Z+n%B*X);
		}
	}
	else{
		for(int i=0;i<=b;i++){
			int n=N-i*B;
			if(n>=0) ret=min(ret,i*Z+n/A*Y+n%A*X);
		}
	}
	return ret;
}
signed main(){
	int T=0;
	scanf("%d",&T);
	for(;T--;){
		scanf("%d%lld%lld%lld%lld%lld",&N,&A,&B,&X,&Y,&Z);
		printf("%lld\n",solve());
	}
	return 0;
}

对了兄弟们,我不卡常了!

标签:lfloor,make,rfloor,性价比,lld%,操作,ll
From: https://www.cnblogs.com/LQ636721/p/17084578.html

相关文章

  • 嵌入式Linux中Makefile万能写法
    嵌入式Linux中Makefile万能写法对于linux系统中使用gcc进行编译:#列出当前目录下所有*.c文件SRC:=$(wildcard*.c)#将所有*.c文件转为*.o文件OBJ:=$(patsubst%.c,%.o......
  • [教程]跟着思兼学习Klipper(20)Makerbase MKS SKIPR 船长板 简要使用记录
    【思兼】MakerbaseMKSSKIPR船长板简要使用记录前言原创文章,转载引用请务必注明链接,水平有限,如有疏漏,欢迎指正交流。文章如有更新请访问DFRobot社区或者cnblogs......
  • CMake语法—选项(option)
    CMake语法—选项(option)1选项1.1定义 1.2说明variable选项名help_text描述、解释、备注value选项初始化值(除ON而外全为OFF)2应用注意事项2.1代......
  • cmake命令之option使用案例
    option的命令形式如下option(<variable>"<help_text>"[value]) option简介    cmake中option起到编译开关的作用,CMakeLists.txt中option以前的语句,变量......
  • CMake option选项开关
    CMakeoption使用场景:编译脚本传递参数->CMake脚本接收option->源代码宏1.编译脚本传入参数传入一个cmakeoptionTEST_DEBUG#!/bin/shcmake-DTEST_DEBUG=ON......
  • Makefile文件
    #编译后的可执行文件名称BIN=stack#收集目录下的所有.c文件SRC=$(wildcard*.c)#调用makefile中的函数patsubst,用.o文件代替.c文件OBJ=$(patsubst%.c,%.o,$(SR......
  • 【KAWAKO】在windows上用CMake和MinGW编译c++工程
    目录安装CMake安装MinGW编写CMakeLists.txt编译一条龙安装CMake在网上随便找个教程照着安装就行了,不再赘述。安装MinGW参考这篇博客。从MinGW官网下载的安装包在安装的......
  • [C++]Makefile概要
    ####Makefile变量和赋值符##延迟赋值: = 变量的正常设置,但值字段中提到的任何其他变量都在使用变量时用其值递归展开,而不是声明变量时的值## 延迟变量使用[......
  • 关于pacemaker中资源启动的位置约束Location Constraints
    默认情况,对于业务应用的资源启动在那里,可能是随机的、有时启动在app01上,也可能启动在app02了我们也可以通过手动配置分数的方式,将某个节点的分数配置到极高,无穷大,这样,资......
  • [LeetCode] 1664. Ways to Make a Fair Array
    Youaregivenanintegerarray nums.Youcanchoose exactlyone index(0-indexed)andremovetheelement.Noticethattheindexoftheelementsmaychangea......