题目来自Dotcpp网站:
对题目分析:
①我们要注意数据读入的问题,它的一行表示An。
②题目要求我们如果有一个国家获胜,要求出最多发生了多少个事件。
暴力思路:
我们可以用DFS 选和不选 的思想,对事件枚举。当 DFS 要返回时,可以先for循环遍历一下,统计一下st数组中 == 1 的个数,这就是发生的总事件。然后在判断一下,这三个国家中有没有一个国家获胜,如果获胜了,就和我们统计的总事件来比较,保证返回的总事件是最大的。最后,输出前判断一下要不要输出 -1 。
DFS代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+10;
int n;
int a[N], b[N], c[N], st[N];
//如果有其中一个国家获胜
//最多发生了多少个事件 要得到最大值
int smax = -1;
//用一个数组记录x,y,z的士兵数量
//1表示x 2表示y 3表示z
int arr[3];
void dfs(int x){
if(x > n){
//记录选的情况
int cnt2 = 0;
for(int i = 1; i <= n; i++){
if(st[i] == 1){
cnt2 += 1;
}
}
//得到它们三个之间的最大值 来判断游戏有没有结束
//要得到他们三个之间最大的那个下标
int cnt = 1;
for(int i = 1; i <= 3; i++){
if(arr[cnt] < arr[i]){
cnt = i;
}
}
//判断游戏能不能结束
int sum = 0;
for(int i = 1; i <= 3; i++){
sum += arr[i];
}
if(arr[cnt] > sum - arr[cnt]){
smax = max(smax, cnt2);
}
return;
}
//选
st[x] = 1;
arr[1] += a[x];
arr[2] += b[x];
arr[3] += c[x];
dfs(x+1);
arr[1] -= a[x];
arr[2] -= b[x];
arr[3] -= c[x];
st[x] = 0;
//不选
st[x] = 2;
dfs(x+1);
st[x] = 0;
}
signed main(){
//读入数据
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
cin >> b[i];
}
for(int i = 1; i <= n; i++){
cin >> c[i];
}
dfs(1);
cout << smax;
return 0;
}
由于直接暴力,然后题目的数据量很大,这样做的话会超时,因此我们要优化。
贪心思路:
①由于题目中告诉我们游戏中只有三个国家,所以我们一次假设其中一个国家获胜。我们可以用一个数组来存储每次事件的情况。(可能大于0 也可能小于0)。
②当我们假设 x 国家获胜,就有:d[x] = x-(y+z),之后对 d 数组排序,定义一个sum,每次选择最大值,用sum统计选择的次数,sum表示的当x国家获胜的时候,最多选择了多少个事件。对于 y,z国家依次用数组来记录选择事件之后的答案。
贪心代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5+10;
int n;
int a[N], b[N], c[N];
int cal(int a[], int b[], int c[], int d[]){
for(int i = 1; i <= n; i++){
d[i] = a[i] - (b[i] + c[i]);
}
//要降序排序
sort(d+1, d+1+n);
reverse(d+1, d+1+n);
int sum = 0;
int cnt = 0;
for(int i = 1; i <= n; i++){
if(d[i] + sum > 0){
sum += d[i];
cnt += 1;
}else{
break;
}
}
return cnt;
}
signed main(){
//读入数据
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
cin >> b[i];
}
for(int i = 1; i <= n; i++){
cin >> c[i];
}
int d[N];
int ans = -1;
//x国家获胜
ans = max(ans, cal(a, b, c, d));
// y 国家获胜
ans = max(ans, cal(b,a,c,d));
//z国家获胜
ans = max(ans, cal(c, a, b, d));
cout << ans <<endl;
return 0;
}