2021HDU多校第三场 1009 Rise in Price 思维+乱搞
Posted kaka0010
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021HDU多校第三场 1009 Rise in Price 思维+乱搞相关的知识,希望对你有一定的参考价值。
原题链接:https://acm.hdu.edu.cn/showproblem.php?pid=6981
题意
有两个n*n的矩阵a,b分别代表每个格子的钻石数量和提升的单价,我们只能从(1,1)开始走到(n,n),问售卖钻石的最大价值是多少。
分析
赛中往DP和网络流方向去想了,很明显发现这个状态根本无法全部表示,记录到当前为止拿到的宝石数量和提升的价格是不可能的,因为这是指数提升的状态。根据题解中描述的,我们只需要取最满足条件的前K个状态保存一下,接着进行合并。
合并的方法也非常简单,只需要利用归并排序的思想,我们将 宝 石 数 ∗ 单 价 宝石数*单价 宝石数∗单价高的状态往前放一放,只需要O(n)的合并复杂度,粗略计算一下复杂度大约是 O ( T ∗ n 2 K ) O(T*n^2K) O(T∗n2K),因此K取100左右就可以了。
Code
#include <bits/stdc++.h>
#define lowbit(i) i & -i
#define Debug(x) cout << x << endl
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PII;
const ll INF = 1e18;
const double eps = 1e-3;
const int N = 1e6 + 10;
const int M = 1e6 + 10;
const int MOD = 998244353;
vector<PII> f[105][105];
int a[105][105], b[105][105];
bool cmp(PII x, PII y) {
return x.fi * x.se >= y.fi * y.se;
}
void merge(vector<PII> &F, vector<PII> f1, vector<PII> f2) {
int l = 0, r = 0;
int SIZE = 105;
while (l < f1.size() && r < f2.size() && F.size() < SIZE) {
if (f1[l].fi * f1[l].se >= f2[r].fi * f2[r].se) {
F.push_back({f1[l].fi, f1[l].se});
l++;
} else {
F.push_back({f2[r].fi, f2[r].se});
r++;
}
}
while (l < f1.size() && F.size() < SIZE) {
F.push_back({f1[l].fi, f1[l].se});
l++;
}
while (r < f2.size() && F.size() < SIZE) {
F.push_back({f2[r].fi, f2[r].se});
r++;
}
sort(F.begin(), F.end(), cmp);
}
void solve() {
int T; cin >> T; while (T--) {
int n; cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
f[i][j].clear();
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> b[i][j];
}
}
f[1][1].push_back({a[1][1], b[1][1]});
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) continue;
else if (i == 1) f[i][j] = f[i][j-1];
else if (j == 1) f[i][j] = f[i-1][j];
else merge(f[i][j], f[i-1][j], f[i][j-1]);
for (auto &it : f[i][j]) it.fi += a[i][j], it.se += b[i][j];
}
}
ll ans = 0;
for (int i = 0; i < f[n][n].size(); i++) {
ans = max(ans, f[n][n][i].fi * f[n][n][i].se);
}
cout << ans << endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}
以上是关于2021HDU多校第三场 1009 Rise in Price 思维+乱搞的主要内容,如果未能解决你的问题,请参考以下文章
hdu多校第三场 1006 (hdu6608) Fansblog Miller-Rabin素性检测