zoukankan      html  css  js  c++  java
  • [題解]luogu_P1052 過河

    來源:題解


    不發題面

    因為 l 範圍太大,而石子數卻很少,步數也僅僅在1~10之間,

    也就是說兩個石子之間很有可能間隔很大的距離,不管怎麼跳都能跳過去,那麼中間那些怎麼樣都能跳過去的區間和沒有等價,

    所以讀入后就更新一遍pos和vis數組,範圍就可以縮到比較小,

    至於具體多大的區間可以刪掉,可以取1~10的最小公倍數2520,(小凱的疑惑)71,(t * t-1)90,甚至可以 %t 再 +t,好像都可以

    大概是一個離散化的方法吧

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int l,s,t,m,ans;
    int p[101],d[101],v[300001];
    int f[300001];
    int main()
    {
        scanf("%d%d%d%d",&l,&s,&t,&m);
        for(int i=1;i<=m;i++){
            scanf("%d",&p[i]);
        }
        if(s==t){
            for(int i=1;i<=m;i++)if(p[i]%t==0)ans++;
            printf("%d",ans);return 0;
        }
        sort(p+1,p+1+m);
        for(int i=1;i<=m;i++){
            d[i]=(p[i]-p[i-1])%2520;//只要兩個石子之間超過1~10的lcm,這一段就相當於沒有,怎麼樣都可以跳過去 
        }
        for(int i=1;i<=m;i++){//更新p[i]和v[i] 
            p[i]=p[i-1]+d[i];
            v[p[i]]=1;
        }
        int l=p[m];
        memset(f,0x3f,sizeof(f));
        f[0]=0;
        for(int i=1;i<=l+t;i++)//這裡l+t是因為有可能跳過,預留出跳過頭的範圍,在在區間內找最小值 
        for(int j=s;j<=t;j++){
            if(i-j>=0)
            f[i]=min(f[i],f[i-j]+v[i]);
        }
        int ans=m;
        for(int i=l;i<l+t;i++)ans=min(ans,f[i]);
        printf("%d",ans);
    }
  • 相关阅读:
    第一章:帝国的余晖 AT&T公司
    个人最终总结——2(完成了第3个问题)
    个人最终总结——1(完成了前面2个问题)
    week9:个人博客作业
    week8:个人博客作业
    week7:个人博客作业
    week6:个人博客作业
    将博客搬至CSDN
    top命令
    java并发编程的艺术-第四章笔记
  • 原文地址:https://www.cnblogs.com/superminivan/p/10539573.html
Copyright © 2011-2022 走看看