蓝桥杯-防御力

1.题目描述

小明最近在玩一款游戏。对游戏中的防御力很感兴趣。
我们认为直接影响防御的参数为“防御性能”,记作d,而面板上有两个防御值A和B,与d成对数关系,A=2d,B=3dA=2 注意任何时候上式都成立)。
在游戏过程中,可能有一些道具把防御值A增加一个值,有另一些道具把防御值B增加一个值。现在小明身上有n1个道具增加A的值和n2个道具增加B的值,增加量已知。
现在已知第i次使用的道具是增加A还是增加B的值,但具体使用那个道具是不确定的,请找到一个字典序最小的使用道具的方式,使得最终的防御性能最大。
初始时防御性能为0,即d=0,所以A=B=1。

输入

输入的第一行包含两个数n1,n2,空格分隔。
第二行n1个数,表示增加A值的那些道具的增加量。
第三行n2个数,表示增加B值的那些道具的增加量。
第四行一个长度为n1+n2的字符串,由0和1组成,表示道具的使用顺序。0表示使用增加A值的道具,1表示使用增加B值的道具。输入数据保证恰好有n1个0,n2个1。

输出

对于每组数据,输出n1+n2+1行,前n1+n2行按顺序输出道具的使用情况,若使用增加A值的道具,输出Ax,x为道具在该类道具中的编号(从1开始)。若使用增加B值的道具则输出Bx。最后一行输出一个大写字母E。

样例输入

1 2
4
2 8
101

样例输出

B2
A1
B1
E

2.题解

2.1 贪心算法

思路

这里的贪心证明使用数学证明并不好证,但我们可以先确定可能的贪心策略,并带入具体数据进行测试,选出最优解(做题技巧)
一共有四种贪心策略:
1.A道具效果从小到大使用,B道具效果从小到大使用
2.A道具效果从小到大使用,B道具效果从大到小使用
3.A道具效果从大到小使用,B道具效果从大到小使用
4.A道具效果从大到小使用,B道具效果从小到大使用

检测:

好的,为了证明策略2(即 A 道具效果从小到大使用,B 道具效果从大到小使用)是最优的,让我们选择一个具体的例子,并进行详细计算和比较。

示例

假设输入数据如下:

  • ( n1 = 2 ), ( n2 = 2 )
  • 增加 ( A ) 值的道具增加量:[4, 6]
  • 增加 ( B ) 值的道具增加量:[8, 3]
  • 使用顺序:[0, 1, 0, 1]

四种贪心策略:

策略1:A 道具效果从小到大使用,B 道具效果从小到大使用

  • A 道具:[4, 6]
  • B 道具:[3, 8]

使用顺序:[0, 1, 0, 1]

  1. 使用 A 道具4
    • ( $A = 1 + 4 = 5 $)
    • ( \(d = \log_2(5) \approx 2.322\) )
    • ( \(B = 3^{2.322} \approx 10.6\) )
  2. 使用 B 道具3
    • ( $B = 10.6 + 3 = 13.6 )
    • ( $d = \log_3(13.6) \approx 2.311 $)
    • ( \(A = 2^{2.311} \approx 4.92\) )
  3. 使用 A 道具6
    • ( $A = 4.92 + 6 = 10.92 )
    • ( \(d = \log_2(10.92) \approx 3.457\) )
    • ( \(B = 3^{3.457} \approx 40.95\) )
  4. 使用 B 道具8
    • ( $B = 40.95 + 8 = 48.95 $)
    • ( $d = \log_3(48.95) \approx 3.663 $)
    • ( $A = 2^{3.663} \approx 12.9 $)

最终防御性能 ( $d \approx 3.663 $)。

策略2:A 道具效果从小到大使用,B 道具效果从大到小使用

  • A 道具:[4, 6]
  • B 道具:[8, 3]

使用顺序:[0, 1, 0, 1]

  1. 使用 A 道具4
    • ( $A = 1 + 4 = 5 $)
    • ( \(d = \log_2(5) \approx 2.322\) )
    • ( \(B = 3^{2.322} \approx 10.6\) )
  2. 使用 B 道具8
    • ( \(B = 10.6 + 8 = 18.6\))
    • ( \(d = \log_3(18.6) \approx 2.715\) )
    • ( \(A = 2^{2.715} \approx 6.55\) )
  3. 使用 A 道具6
    • ( \(A = 6.55 + 6 = 12.55\) )
    • ( \(d = \log_2(12.55) \approx 3.647\) )
    • ( \(B = 3^{3.647} \approx 53.1\) )
  4. 使用 B 道具3
    • ( $B = 53.1 + 3 = 56.1 $)
    • ( \(d = \log_3(56.1) \approx 3.828\) )
    • ( \(A = 2^{3.828} \approx 14.5\) )

最终防御性能 ( $d \approx 3.828 $)。

策略3:A 道具效果从大到小使用,B 道具效果从大到小使用

  • A 道具:[6, 4]
  • B 道具:[8, 3]

使用顺序:[0, 1, 0, 1]

  1. 使用 A 道具6
    • ( \(A = 1 + 6 = 7\) )
    • ( \(d = \log_2(7) \approx 2.807\) )
    • ( \(B = 3^{2.807} \approx 18.5\) )
  2. 使用 B 道具8
    • ( \(B = 18.5 + 8 = 26.5\) )
    • ( $$d = \log_3(26.5) \approx 3.008$ )
    • ( \(A = 2^{3.008} \approx 8.03\) )
  3. 使用 A 道具4
    • ( \(A = 8.03 + 4 = 12.03\) )
    • ( \(d = \log_2(12.03) \approx 3.584\) )
    • ( \(B = 3^{3.584} \approx 49.9\) )
  4. 使用 B 道具3
    • ( \(B = 49.9 + 3 = 52.9\) )
    • ( \(d = \log_3(52.9) \approx 3.775\) )
    • ( \(A = 2^{3.775} \approx 13.9\) )

最终防御性能 ( \(d \approx 3.775\) )。

策略4:A 道具效果从大到小使用, B 道具效果从小到大使用

  • A 道具:[6, 4]
  • B 道具:[3, 8]

使用顺序:[0, 1, 0, 1]

  1. 使用 A 道具6
    • ( $A = 1 + 6 = 7 $)
    • ( \(d = \log_2(7) \approx 2.807\) )
    • ( \(B = 3^{2.807} \approx 18.5\) )
  2. 使用 B 道具3
    • ( \(B = 18.5 + 3 = 21.5\) )$
    • ( \(d = \log_3(21.5) \approx 2.924\) )
    • ( \(A = 2^{2.924} \approx 7.56\) )
  3. 使用 A 道具4
    • ( \(A = 7.56 + 4 = 11.56\) )
    • ( \(d = \log_2(11.56) \approx 3.529\) )
    • ( \(B = 3^{3.529} \approx 47.9\) )
  4. 使用 B 道具8
    • ( \(B = 47.9 + 8 = 55.9\) )
    • ( \(d = \log_3(55.9) \approx 3.825\) )
    • ( \(A = 2^{3.825} \approx 14.48\) )

最终防御性能 ( d \approx 3.825 )。

结论

通过比较不同策略的最终防御性能 (d):

  • 策略1:( \(d \approx 3.663\) )
  • 策略2:( $d \approx 3.828 $)
  • 策略3:( \(d \approx 3.775\) )
  • 策略4:( \(d \approx 3.825\) )

可以看出,策略2(A道具效果从小到大使用,B道具效果从大到小使用)得到了最高的最终防御性能 ( \(d \approx 3.828\) )。

因此,策略2在这个例子中确实是最优的。

然后我们很容易发现使用第2种策略是最优的,大概数学证明如下:

我们可以发现A和B增大同样的大小,\(d=log_2(A), d=log_3(B)\), A对于d的影响更大,提升速度更快,由于增大量x是固定的,但是每次对d的影响实际上取决于 x/A, 我们希望每次增量都使这种提升最大,充分利用每一次增量,就要求每次使用这个x之前,之前积累的和A越小越好,也就是A增量从小到大,但同时B的增大也会通过影响d反过来影响A的增大,我们希望尽量减小A的增大,也就是令x/B越小越好,让B从大到小即可。

代码

#include<bits/stdc++.h>
using namespace std;
bool compare1(pair<int,int> p1, pair<int, int> p2){
	if(p1.second != p2.second)
		return p1.second < p2.second;
	return p1.first <= p2.first;
}

bool compare2(pair<int,int> p1, pair<int, int> p2){
	if(p1.second != p2.second)
		return p1.second > p2.second;
	return p1.first <= p2.first;
}
int main(){
	int n1, n2;
	cin >> n1 >> n2;
	
	vector<pair<int,int>> items1(n1), items2(n2);
	for(int i = 0; i < n1; i++){
		items1[i].first = i + 1;
		cin >> items1[i].second;
	}
	for(int i = 0; i < n2; i++){
		items2[i].first = i + 1;
		cin >> items2[i].second;
	}
	string op;
	cin >> op;
	
	sort(items1.begin(), items1.end(),compare1);
	sort(items2.begin(), items2.end(), compare2);
	int cnt1 = 0, cnt2 = 0;
	for(char ch : op){
		if(ch == '0'){
			printf("A%d\n",items1[cnt1++].first);
		} else{
			printf("B%d\n",items2[cnt2++].first);
		}
	}
	printf("E");
	return 0;
} 
posted @ 2024-06-19 10:21  DawnTraveler  阅读(5)  评论(0编辑  收藏  举报