資源箱 ZZULIOJ - 2478 貪心
阿新 • • 發佈:2018-12-23
題解
最大方案 先將兩個貨物高度持平 再判斷當前高度下哪個貨物比較重(包含累加的重量) 移動較重的到另一側
最小方案 對兩堆貨物求和 和較小的為最小方案 注意反向輸出
求最大方案時需要先輸出最大值再輸出移動方案 可以用stringstream流將輸出存起來後面直接輸出
AC程式碼
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int a[MAXN], b[MAXN];
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
int N, M;
ll sa = 0, sb = 0; //ab求和
cin >> N >> M;
for (int i = 1; i <= N; i++)
scanf("%lld", &a[i]), sa += a[i];
for (int i = 1; i <= M; i++)
scanf("%lld", &b[i]), sb += b[i];
ll tot = 0, mx = 0; //已經移動過的重量 最大答案
int i = N, j = M, k = 0; //ab最高位置 移動過的在a還是b上0為a
stringstream ss; //將輸出用字串流先儲存起來
while (i && j) //一個到底則結束 先持平再儘量移動重的
{
if (i > j || i == j && a[i] + tot * !k > b[j] + tot * k) //a高或者a頂部重
{
ss << "A>" << a[i] + tot * !k << ">B\n";
mx += a[i] + tot * !k; //記錄答案
tot += a[i--], k = 1; //將A上移動到B
}
else if (i < j || i == j && a[i] + tot * !k < b[j] + tot * k)
{
ss << "B>" << b[j] + tot * k << ">A\n";
mx += b[j] + tot * k;
tot += b[j--], k = 0;
}
}
cout << mx << endl; //輸出最大方案
cout << ss.str();
cout << min(sa, sb) << endl; //輸出最小方案
if (sa < sb)
for (int i = N; i >= 1; i--)
printf("A>%d>B\n", a[i]);
else
for (int i = M; i >= 1; i--)
printf("B>%d>A\n", b[i]);
}
return 0;
}