[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;   
}
posted @ 2024-11-13 19:12  Qian·JXのjoker  阅读(3)  评论(0编辑  收藏  举报