多校第三场 Rise in Price(模拟)
Posted zjj0624
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多校第三场 Rise in Price(模拟)相关的知识,希望对你有一定的参考价值。
题意
给你一个
n
∗
n
n*n
n∗n的网格,每个点都有一个
a
i
,
b
i
a_i,b_i
ai,bi,让你求从
(
1
,
1
)
(1,1)
(1,1)走到
(
n
,
n
)
(n,n)
(n,n)的最优路径,使得
∑
a
i
j
×
∑
b
i
j
∑ a _ij × ∑ b _ij
∑aij×∑bij。
思路
刚开始我第一时间想到的是用DP转移,但是因为有a,b两个元素,没法转移,而且如果DP的话时间复杂度是
o
(
n
2
)
o(n^2)
o(n2)才1e4,时间还绰绰有余,所以我们可以对每个点都存下来一些状态,然后进行转移,我们可以对每个点存100个状态,我们要从上一个状态中选出最优的100个状态,也就是suma*sumb比较大的状态存下来,然后转移就可以,为什么是100个状态就能找出答案我也不太清楚,也有可能是数据比较水。。
代码
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N=110;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll a[N][N],b[N][N];
vector<PLL>v[N][N];
bool cmp(PLL x,PLL y)
return x.fi*x.se>y.fi*y.se;
int main()
int t;
cin>>t;
while(t--)
int n;
cin>>n;
for(int i=1 ; i<=n ; i++)
for(int j=1 ; j<=n ; j++)
v[i][j].clear();
for(int i=1 ; i<=n ; i++)
for(int j=1 ; j<=n ; j++)
cin>>a[i][j];
for(int i=1 ; i<=n ; i++)
for(int j=1 ; j<=n ; j++)
cin>>b[i][j];
v[1][1].push_back(a[1][1],b[1][1]);
for(int i=1 ; i<=n ; i++)
for(int j=1 ; j<=n ; j++)
vector<PLL>p;
if(i==1&&j==1) continue;
for(int k=0 ; k<v[i-1][j].size() ; k++) p.push_back(v[i-1][j][k]);
for(int k=0 ; k<v[i][j-1].size() ; k++) p.push_back(v[i][j-1][k]);
sort(p.begin(),p.end(),cmp);
int cnt=0;
for(int k=0 ; k<p.size() ; k++)
cnt++;
v[i][j].push_back(p[k].fi+a[i][j],p[k].se+b[i][j]);
if(cnt>=50) break;
ll ans=0;
for(int i=0 ; i<v[n][n].size() ; i++) ans=max(ans,v[n][n][i].fi*v[n][n][i].se);
cout<<ans<<endl;
return 0;
以上是关于多校第三场 Rise in Price(模拟)的主要内容,如果未能解决你的问题,请参考以下文章