标签:mes namespace 链接 break game bsp set copy 简单贪心
一道打着洛谷黑题招牌的简单贪心
有两个人S和M,他们每人有一段长度为N的数字,两个人在每一轮游戏中都可以按顺序拿出一个数字,谁的数字小谁就接受一次惩罚。若相等两者都没有惩罚。另外,M珂以重新安排自己数字的顺序,问 M的最少被惩罚次数 和 S的最多被惩罚次数 是多少。
输入的第一行包含一个整数n (1<=n<=1000)——S和M将要使用的纸牌中的数字。
第二行包含n个没有空格数字——S的数字。
第三行包含n个没有空格数字——M的数字。
第一行先把M最少受罚次数输出。
第二行输出S最多的受罚次数。
有点类似于田忌赛马的问题, 可以想到用贪心的最优策略
求S最小受罚次数
M可以按任意顺序拿出数字,枚举遍历S中的每一个数,对于每一个数 a 只有两种情况:
W中有还未用且 ≥ a 的数,此时选满足条件的最小的数
W中的数都 < a 的数, 此时选未用的数中最小的数
for (int i = 1; i <= len; i++) { bool ok = 0; for (int j = 1; j <= len; j++) if (a[j] >= b[i] and !used[j]) {ok = 1, used[j] = 1; break;} if (!ok) for (int j = 1; j <= len; j++) if (!used[j]) {used[j] = 1, ans1++; break;} }
求M最大受罚数
做法相似,枚举遍历S中的每一个数,对于每一个数 a 只有两种情况:
W中有还未用且 > a 的数,此时选满足条件的最小的数
W中的数都 ≤ a 的数, 此时选未用的数中最小的数
for (int i = 1; i <= len; i++) { bool ok = 0; for (int j = 1; j <= len; j++) if (a[j] > b[i] and !used[j]) {ok = 1, used[j] = 1, ans2++; break;} if (!ok) for (int j = 1; j <= len; j++) if (!used[j]) {used[j] = 1; break;} }
#include <bits/stdc++.h> using namespace std; char a[1005], b[1005]; bool used[1005]; //used记录是否被用 int len, ans1, ans2; //ans1记录 M 最少受罚次数, ans2记录 S 最多受罚次数 int main() { scanf ("%d %s %s", &len, b + 1, a + 1); sort (a + 1, a + len + 1); //第一问: for (int i = 1; i <= len; i++) { bool ok = 0; //ok记录是否有满足要求的数 for (int j = 1; j <= len; j++) if (a[j] >= b[i] and !used[j]) {ok = 1, used[j] = 1; break;} //如果没有则选最小的数 if (!ok) for (int j = 1; j <= len; j++) if (!used[j]) {used[j] = 1, ans1++; break;} //此时受罚次数 +1; } memset (used, 0, sizeof (used)); //清零used数组 //第二问: for (int i = 1; i <= len; i++) { bool ok = 0; //ok记录是否有满足要求的数 for (int j = 1; j <= len; j++) if (a[j] > b[i] and !used[j]) {ok = 1, used[j] = 1, ans2++; break;} //如果没有则选最小的数 if (!ok) for (int j = 1; j <= len; j++) if (!used[j]) {used[j] = 1; break;} //此时不受罚次数 +1; } printf ("%d\n%d", ans1, ans2); return 0; }
标签:mes namespace 链接 break game bsp set copy 简单贪心
原文地址:https://www.cnblogs.com/whx666/p/10503587.html