Official
E - 展示会の配置 / Exhibition Layout Editorial
by
E - 展示会の配置 / Exhibition Layout Editorial
by
physics0523
この問題は、以下の bitDP で解くことができます。
- \(dp[S][i] = \{\) 既に配置したアイテムの集合が \(S\) で、そのうち最後に配置したアイテムが \(i\) であるときの、既に確定した評価値の総和の最大値 \(\}\)
bitDP の形としては巡回セールスマン問題とよく似た形をしています。
しかし、「アイテムを既に \(c\) 個置いた状態で、アイテム \(i\) の次にアイテム \(j\) を置く時の評価関数の増分」が \(c,i,j\) 全てに依存することに注意してください。
\(S\) から既に配置されたアイテムの個数を抽出することで、次にアイテム \(j\) を置いた時の評価値の増分を求めることができます。
時間計算量は \(O(2^NN^2)\) です。
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
ll gap(ll x,ll y){
return max(x,y)-min(x,y);
}
int main(){
int n;
cin >> n;
vector<ll> p(n),w(n-1);
for(auto &nx : p){cin >> nx;}
for(auto &nx : w){cin >> nx;}
vector<vector<ll>> dp(1<<n,vector<ll>(n,-8e18));
for(int i=0;i<n;i++){
dp[1<<i][i]=0;
}
for(int i=0;i<(1<<n);i++){
int pc=__builtin_popcount(i)-1;
for(int j=0;j<n;j++){
if(dp[i][j]<0){continue;}
for(int k=0;k<n;k++){
if(i&(1<<k)){continue;}
dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+gap(p[j],p[k])*w[pc]);
}
}
}
ll res=0;
for(int j=0;j<n;j++){
res=max(res,dp[(1<<n)-1][j]);
}
cout << res << "\n";
return 0;
}
posted:
last update:
