首页 > 其他分享 >CF10E Greedy Change 题解

CF10E Greedy Change 题解

时间:2022-11-02 15:58:30浏览次数:76  
标签:le Rightarrow int 题解 CF10E 位为 贪心 Change 字典

http://codeforces.com/problemset/problem/10/E

题意

给出货币系统 \(\{c_n\}\) 满足 \(c_1>c_2>\cdots>c_n=1\),请找到最小的 \(x\) 使贪心算法需要的货币数目比最优解多。

贪心算法:每次取最大的不超过 \(x\) 的货币。

\(1\le n\le400,1\le c_i\le10^9\)

题解

把 \(x\) 的货币系统表示记作向量 \(V\),即 \(V\cdot C=x\)。

令向量 \(M(x)\) 为表示 \(x\) 字典序最大的最优解,\(G(x)\) 为贪心解(是字典序最大的表示)。

这样限制可以直接比较两个向量。开始推性质(下面的比较都是字典序):

  • \(\forall x<y,M(x)<M(y)\)

  • \(M\) 的子集是最优的表示,\(G\) 的子集是贪心表示。

这些都由定义易得。

定义 \(s\) 为最小的解,这样取一个子集之后 \(M,G\) 是相等的,可以找一些必要条件:

  • \(M(s),G(s)\) 非零位无交。

如果 \(M,G\) 的第 \(i\) 位均大于 \(0\),\(s-c_i\) 是比 \(s\) 更优的解,矛盾。

设 \(i,j\) 为 \(M(s)\) 的最低和最高非零位。

  • \(G(s-c_j)\) 前 \(i-1\) 位为 \(0\)。

\(M(s)\) 前 \(i-1\) 位为 \(0\) \(\Rightarrow\) \(M(s-c_j)\) 前 \(i-1\) 位为 \(0\) \(\Rightarrow\) \(G(s-c_j)\) 前 \(i-1\) 位为 \(0\)。

推论:\(s-c_j<c_{i-1}\)。

  • \(G(s)\) 在前 \(i-1\) 位有非零位。

\(G(s)\) 第 \(i\) 位一定是 \(0\),如果前 \(i-1\) 位也全部是 \(0\),那么字典序就小于 \(M(s)\) 了,与定义矛盾。

推论:\(s\ge c_{i-1}\)。

现在整理一下限制,因为 \(c_i\) 的数量不多,想要建立和 \(M(s)\) 的关系:

\(s\ge c_{i-1}\Rightarrow c_{i-1}-1-c_i<s-c_i\Rightarrow G(c_{i-1}-1-c_i)<G(s-c_i)=M(s-c_i)\)

发现把向量第 \(i\) 位加 \(1\) 仍是符合定义的。

对于 \(G\) 考虑贪心过程是显然的。

对于 \(M\),\(M(s-c_i)\) 是 \(M(s)\) 的子集,至少需要再某一位加 \(1\),必然是第 \(i\) 位。

于是得到 \(G(c_{i-1}-1)<M(s)\)。

从另一个限制出发:

\(s-c_j\le c_{i-1}-1\Rightarrow M(s-c_j)=G(s-c_j)\le G(c_{i-1}-1)\)

本来 \(M(s)\) 字典序大于 \(G(c_i-1)\),第 \(j\) 位减 \(1\) 后就小于等于了。

首先它们 \(j\) 位之前相等。由于 \(M(s)\) 第 \(j\) 位之后都是 \(0\) ,所以 \(M(s)\) 第 \(j\) 位恰好为 \(G(c_{i-1})\) 第 \(j\) 为加 \(1\)。

现在可以枚举 \(i,j\),\(O(n)\) check,时间复杂度 \(O(n^3)\)。

代码:

#include <bits/stdc++.h>
using namespace std;
const int inf=2e9;
int main(){
	int n,ans=inf;
	scanf("%d",&n);
	vector<int> c(n);
	for(int&x:c) scanf("%d",&x);
	auto val=[&](int x){
		int res=0;
		for(int v:c) res+=x/v,x%=v;
		return res;
	};
	for(int i=1;i<n;i++){
		int s=c[i-1]-1,x=s,m=0;
		for(int j=i;j<n;j++){
			m+=x/c[j];x%=c[j];
			if(m+1<val(s-x+c[j])) ans=min(ans,s-x+c[j]);
		}
	}
	printf("%d\n",ans==inf?-1:ans);
	return 0;
}

标签:le,Rightarrow,int,题解,CF10E,位为,贪心,Change,字典
From: https://www.cnblogs.com/shrshrshr/p/16850735.html

相关文章

  • BAPI_RESERVATION_CHANGE 删除预留
    CLEAR:reservationitems[],reservationitems.CLEAR:reservationitemsx[],reservationitemsx,reservation.reservation=gt_resb-rsnum.reservat......
  • 未能加载文件或程序集 或它的某一个依赖项。试图加载格式不正确的程序。问题解决
    原因分析:操作系统是64位的,但发布的程序引用了一些32位的ddl,所以出现了兼容性的问题。 解决方案:IIS——应用程序池——高级设置——启用32位应用程序:true。下图这个地方......
  • CSP-S 2022 第二轮 题解
    T1.假期计划(holiday)这个题作为t1可一点都不简单啊。先用bfs\(O(nm)\)求出任意两点之间的最短路,这样就可以判断哪些点对可以排在一起。注意到第1、4个景点是对称的,第......
  • 「题解」Codeforces 1322B Present
    看上去异或里面套了层加法不好拆位,但是依然可以对每个二进制位处理。现在考虑第\(k\)位,那么产生贡献的数字对一定满足以下条件之一:第\(k\)位相同且前\((k-1)\)位......
  • 「题解」Codeforces 930E Coins Exhibition
    看到题就先容斥。然后容斥系数太难算了就寄了,大概要分好几种情况讨论,于是就弃了。不容斥也能做。考虑限制将串划分成了若干段,然后一段一段dp.有没有什么好的方法描述这个......
  • 20221102模拟赛题解
    A-Holy思路由于要让最小值最大,不难想到二分答案。二分后将原矩阵中大于等于\(mid\)的值设为\(1\),小于的设为\(0\),然后将每一行压成二进制,存在两行满足要求当且仅当两......
  • CSP-S 2022 题解
    「CSP-S2022」假期计划\(1\toa\tob\toc\tod\to1\)中\(a,b,c,d\)是\(4\)个不同的景点是突破点,数据范围允许枚举其中的两个。便很自然想到枚举中间的\(b,c\),并......
  • 2022年4月第十三届蓝桥杯省赛C组C语言 习题解析(每日一道)
    试题B:特殊时间   【问题描述】           2022年2月22日22:20是一个很有意义的时间,年份为2022,由3个2和1个0组   成,如果将月和日......
  • 洛谷 P8820 [CSP-S 2022] 数据传输 题解
    首先考虑对于每一次询问暴力DP。设\(f_{u,i}\)表示从\(s\)开始,传到一个到\(u\)距离为\(i\)的点,需要的最短时间。当\(k=3\)时,可能会传到不在\(s\tot\)路......
  • spring-boot 配置 swagger常见版本不匹配问题解决方案
    https://stackoverflow.com/questions/70036953/spring-boot-2-6-0-spring-fox-3-failed-to-start-bean-documentationpluginsboo一般出现在2.6.*的springboot版本,这里解......