[ARC105C] Camels and Bridge 题解
[ARC105C] Camels and Bridge 题解
https://www.luogu.com.cn/problem/AT_arc105_c
记:这是24年夏天在北京梦熊写的(模拟赛撞原),希望这年夏天 fowever 。
sol
首先 \(n\) 很小,所以可以去暴力枚举顺序,也就是全排列。
\(W_s\) 表示排列为 \(s\) 时的间距。又令 \(f_i\) 为前 \(i\) 只的最优决策,即最短距离,然后直接状态转移。
核心代码
do{
f[0]=0;
FOR(i,2,n)
{
int now=1<<(p[i]-1);
f[i]=0;
for(int j=i-1;j;j--)
{
now|=1<<(p[j]-1);
f[i]=max(f[i],f[j]+w[now]);//这里是状态转移方程
}
}
ans=min(ans,f[n]);
}while(next_permutation(p+1,p+n+1));
总代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
int p[10];
const int N=1e5+5;
int f[N];
int w[N];
int a[N];
int v[N];
int l[N];
#define inf 0x3f3f3f3f
int ans=inf;
#define FOR(i,_l,_r) for(int i=_l;i<=_r;i++)
int main()
{
cin>>n>>m;
FOR(i,1,n) cin>>a[i];
FOR(i,1,m) cin>>l[i]>>v[i];
FOR(i,1,n)
FOR(j,i,m)
{
if(a[i]>v[j])
{
puts("-1");
return 0;
}
}
FOR(S,1,(1<<n)-1)
{
int len=0;
FOR(i,1,n) if((S>>(i-1))&1) len+=a[i];
FOR(i,1,m) if(len>v[i]) w[S]=max(w[S],l[i]);
}
FOR(i,1,n) p[i]=i;
do{
f[0]=0;
FOR(i,2,n)
{
int now=1<<(p[i]-1);
f[i]=0;
for(int j=i-1;j;j--)
{
now|=1<<(p[j]-1);
f[i]=max(f[i],f[j]+w[now]);//这里是状态转移方程
}
}
ans=min(ans,f[n]);
}while(next_permutation(p+1,p+n+1));
cout<<ans;
return 0;
}