当前位置: 代码迷 >> 综合 >> Camels and Bridge[ARC105C][二分+Dp]
  详细解决方案

Camels and Bridge[ARC105C][二分+Dp]

热度:104   发布时间:2023-11-19 10:01:52.0

文章目录

  • 题目
  • 思路
  • 代码

题目

Atcoder
nnn 只骆驼,第 iii 只重量为 wiw_iwi? 现在通过 mmm 座桥,每个桥长度为 lil_ili?,承重为 viv_ivi? (允许骆驼踩在端点 000lil_ili? ),安排骆驼顺序使得队列长度最小
n≤8,m≤105n\le 8,m\le10^5n8,m105

思路

首先排列枚举骆驼过桥顺序,然后 dpdpdp 检验
fif_ifi? :前 iii 只骆驼过桥最短长度
f1=0f_1=0f1?=0

然后有

fi=max(fj+len(j,i))f_i=max(f_j+len(j,i))fi?=max(fj?+len(j,i))

考虑为什么合理

然后考虑如何快速求出 lenlenlen ,判断一段骆驼最短长度
可以发现路长承重对路短的有限制
然后路按长度升序,承重也升序了
找到最长的无法承重的桥的长度就是这段骆驼的承重
确实比它短的可能也过不去
在这里插入图片描述
但就不是这段骆驼的问题了

代码

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define int LL
int read(){
    int f=0,x=0;char c=getchar();while(c<'0'||'9'<c){
    if(c=='-')f=1;c=getchar();}while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return !f?x:-x;
}
#define mp make_pair
const int MAXN=100000;
const int INF=1000000000000000000ll;
pair<int,int> c[MAXN+5];
int n,m,w[10],p[10],f[10],s[10];
int cal(int x){
    int L=0,R=m+1;while(L+1<R){
    int Mid=(L+R)>>1;if(c[Mid].second<x)L=Mid;else R=Mid;}return c[L].first;
}
signed main(){
    n=read(),m=read();for(int i=1;i<=n;i++)w[i]=read(),p[i]=i;for(int i=1;i<=m;i++)c[i].first=read(),c[i].second=read();//l_i,v_isort(c+1,c+m+1);int Min=INF;for(int i=m;i>=1;i--)Min=min(Min,c[i].second),c[i].second=Min;for(int i=1;i<=n;i++)if(Min<w[i]){
    puts("-1");return 0;}int ans=INF;do{
    memset(f,0,sizeof(f));for(int i=1;i<=n;i++)s[i]=s[i-1]+w[p[i]];for(int i=2;i<=n;i++)for(int j=1;j<=i-1;j++)f[i]=max(f[i],f[j]+cal(s[i]-s[j-1]));ans=min(ans,f[n]);}while(next_permutation(p+1,p+n+1));printf("%lld\n",ans);return 0;
}
  相关解决方案