题解 CF1372E Omkar and Last Floor
题解 CF1372E Omkar and Last Floor
首先,因为\((a+b)^2\geq a^2+b^2\),所以我们总是希望让\(1\)更加“集中”。当然,这只是一个抽象的原则,具体决策还得靠DP。
考虑区间DP。
设\(dp[i][j]\)表示对于\([i\dots j]\)这些列,只考虑被\([i,j]\)完全包含的区间,能达到的最大价值。
转移时,我们枚举一个\(k\in[i,j]\),表示把\(1\)尽可能集中到第\(k\)列。设所有跨过\(k\)且被\([i,j]\)完全包含的区间数量为\(\text{cnt}(k)\)。则:
\[dp[i][j]=\max_{k\in[i,j]}\{dp[i][k-1]+dp[k+1][j]+\text{cnt}(k)^2\}
\]
答案就是\(dp[1][m]\)。
时间复杂度\(O(nm^3)\)。
参考代码:
//problem:CF1372E
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mk make_pair
#define lob lower_bound
#define upb upper_bound
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T>inline void ckmax(T& x,T y){x=(y>x?y:x);}
template<typename T>inline void ckmin(T& x,T y){x=(y<x?y:x);}
const int MAXN=100;
const int INF=1e9;
int n,m,st[MAXN+5][MAXN+5],ed[MAXN+5][MAXN+5];
vector<pii> seg[MAXN+5];
int dp[MAXN+5][MAXN+5];
int main() {
cin>>n>>m;
for(int i=1;i<=n;++i){
int sz;cin>>sz;
seg[i].resize(sz);
for(int j=0;j<sz;++j){
cin>>seg[i][j].fi>>seg[i][j].se;
for(int k=seg[i][j].fi;k<=seg[i][j].se;++k){
st[i][k]=seg[i][j].fi;
ed[i][k]=seg[i][j].se;
}
}
}
for(int i=1;i<=m;++i){
for(int j=1;j<=m;++j){
dp[i][j]=-INF;
if(i==j){
int cnt=0;
for(int k=1;k<=n;++k)
cnt+=(st[k][i] == ed[k][i]);
dp[i][j]=cnt*cnt;
}
}
}
for(int len=2;len<=m;++len){
for(int i=1;i+len-1<=m;++i){
int j=i+len-1;
for(int k=i;k<=j;++k){
int cnt=0;
for(int l=1;l<=n;++l)
cnt+=(st[l][k]>=i && ed[l][k]<=j);
ckmax(dp[i][j],(k==i?0:dp[i][k-1])+(k==j?0:dp[k+1][j])+cnt*cnt);
}
}
}
cout<<dp[1][m]<<endl;
return 0;
}