CF10E 题解

传送门

n 种货币。找一个最小的金额 x,使得贪心法付款不是最优解;如果贪心法始终都是最优解,输出 1(n400)

将货币集合记作一个 n 维向量 C=(c1,c2,,cn)。对于金额 x 的一个表示法,也记作一个 n 维向量 V。即 C×V=x

记金额 x 的贪心表示法为 G(x),最小表示法为 M(x)。同时要求这两个表示法都是字典序最大的。

易证 G(x) 的子集也是贪心表示,M(x) 的子集也是最小表示。

w 是最小的使得 G(w)M(w) 的金额。因为 w 最小,所以 G(w),M(w) 一定不存在一个维度上都是非零的,否则可以让 w 更小。

i,jM(w) 的最小和最大的非零位。(比如 M(w)=(0,1,1,0,2,0)i=2,j=5

结论:M(w)G(ci11)1,,j1位相同,第 j 位大 1

证明:

G(w)1i1 维上一定有非零的,否则因为非零位无交,G(w) 的第 i 维一定是 0,但是因为 M(w)i 维非零,所以 wci1,与贪心法矛盾。所以 wci1。(1)

因为 w 是最小的,所以 G(wcj)=M(wcj)。因为 iM(w) 最小的非零位,且 M(w),M(wcj) 的区别只有第 j 维差一,所以 M(wcj) 的前 i1 位都是 0

G(wcj)=M(wcj) 得出 G(wcj) 的前 i1 位都是 0。所以 wcj<ci1。(2)

由(1):ci11ci<wci。所以 G(ci11ci)<G(wci)=M(wci),两边都给第 i 位加一,得到 G(ci11)<M(w)。(3)

由(2)有 wcjci11,则 G(wcj)G(ci11),所以 M(wcj)G(ci11)。(4)

结合(3)(4),发现 M(wcj)G(ci11)<M(w)

这说明第 j 维的变动会导致它们大小关系变化,因此 M(w),G(w) 的前 j1 维相等。而 M(w) 在第 j 维之后都是 0(因为 j 是最大的非零位),因此 M(w) 的第 j 维大于 G(w) 的第 j 维。

那有没有可能 M(w).jG(w).j2 呢?不可能,因为 wcj<ci1w

于是我们证明了这个结论。(是不是都忘记我们要证明什么了?)

但是怎么转换到代码上?

int G(int x) { //x用贪心法的答案 
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		int d = x / c[i];
		ans += d;
		x -= c[i] * d;
	}
	return ans;
}
//...
int ans = 0x3f3f3f3f;
	for (int i = 2; i <= n; i++) {
		int x = c[i - 1] - 1;
		int cnt = 0; //把j理解成可以用到哪一位,cnt会维护贪心法的答案
		for (int j = i; j <= n; j++) {
			int d = x / c[j];
			cnt += d;
			x -= c[j] * d; //维护i~j贪心法答案
			if (cnt + 1 < G(c[i - 1] - 1 - x + c[j]))
				ans = min(ans, c[i - 1] - 1 - x + c[j]); 
        //因为M(w)和G(c[i-1]-1)只有第j维相差1,所以M(w)的数量就是cnt+1
        //此时cnt对应的w=c[i-1]-1-x+c[j],因为cnt维护的是i~j维的贪心法,所以要减去x;但是因为M(w)比G(c[i-1]-1)的第j维大1,所以要+c[j]
		}
	}
posted @   FLY_lai  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示