noip济南清北冲刺班DAY2

 

noip济南清北冲刺班DAY2

noip济南清北冲刺班DAY2

题解:

贪心+dp

30% N<=5  5!枚举一下

20%  高度没有的时候,高度花费就不存在了,将ci排序,

从小到大挨个跳。另外,20% 准备跳楼没有花费,那么跳

楼的高度一定是从小到大,或者是从大到小。所以按照hi从

小到大排序,那么跳楼一定是排序后连续的一段。枚举第一

栋楼从哪开始跳。对于100% (1)hi从小到大排序,最后高度

的花费一定是hend-hstart。那么start—end中间楼的高度就

不会造成影响,只需要将start—end中间的楼排序,取小的ci。

(2)现在跳在第i栋楼上,已经跳了j栋楼了的最小花费。

f[i][j]—>min{ f[k][j+1]+c[k]+abs{h[i]-h[k]} }

最后答案是枚举i,j。

代码:

暴力挂了20

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define maxn 60
using namespace std;

int n,t,ans,flag1,flag2,flag3;
int vis[maxn];

struct Build{
    int h,c;
}b[maxn];

inline int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}

bool cmp1(Build a,Build b){
    return a.c<b.c;
}

bool cmp2(Build a,Build b){
    return a.h<b.h;
}

void dfs(int nxt,int now,int sum){
    sum+=b[now].c;
    if(sum>t)return;
    ans=max(ans,nxt-1);
    for(int i=1;i<=n;i++){
        if(vis[i]==0){
            vis[i]=1;
            if(nxt==1){
                dfs(nxt+1,i,sum);
                vis[i]=0;
            }else {
                dfs(nxt+1,i,sum+abs(b[now].h-b[i].h));
                vis[i]=0;
            }
        }
    }
    return;
}

int main(){
    freopen("meet.in","r",stdin);
    freopen("meet.out","w",stdout);
    n=read();flag1=true;flag2=true;
    for(int i=1;i<=n;i++)b[i].c=read();
    for(int i=1;i<=n;i++)b[i].h=read();
    t=read();
    if(n<=5){
        dfs(1,0,0);
        printf("%d\n",ans);
        fclose(stdin);fclose(stdout);
        return 0;
    }
    for(int i=2;i<=n;i++){
        if(b[i].h!=b[i-1].h){
            flag1=false;break;
        }
    }
    if(flag1){
        int ret=0;
        sort(b+1,b+n+1,cmp1);
        for(int i=1;i<=n;i++){
            if(t-b[i].c>0){
                ret++;t-=b[i].c;
            }
        }
        printf("%d\n",ret);
        fclose(stdin);fclose(stdout);
        return 0;
    }
    for(int i=1;i<=n;i++){
        if(b[i].c){
            flag2=false;break;
        }
    }
    if(flag2){
        sort(b+1,b+n+1,cmp2);
        for(int len=1;len<=n;len++){
            flag3=false;
            for(int st=1;st+len-1<=n;st++){
                int ed=st+len-1,pre=b[st].h,f=0;
                for(int i=st;i<=ed;i++){
                    f+=b[i].h-pre;
                    pre=b[i].h;
                }
                if(f<=t)flag3=true,ans=max(ans,len);
            }
            if(flag3==false)break;
        }
        printf("%d\n",ans);
        fclose(stdin);fclose(stdout);
        return 0;
    }
    dfs(1,0,0);
    printf("%d\n",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}
50

相关文章:

  • 2022-12-23
  • 2022-02-24
  • 2021-06-01
  • 2021-07-16
  • 2021-12-16
  • 2021-11-07
  • 2021-08-26
猜你喜欢
  • 2022-12-23
  • 2021-09-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案