[vijos1002][NOIP2005]过河

Description

给定一条数轴,起点为\(0\),数轴的某些整数点上有石子。每次可以移动的区间为\([S,T]\)。求当到达或超过\(L\)时,最少踩到的石子数。

Input

输入的第一行有一个正整数\(L(1\;\leq\;L\;\leq\;10^9)\)

第二行有三个正整数\(S,T,M,M\)表示桥上石子的个数,其中\(1\;\leq\;S\;\leq\;T\;\leq\;10,1\;\leq\;M\;\leq\;100\)

第三行有\(M\)个不同的正整数分别表示这\(M\)个石子在数轴上的位置(数据保证桥的\(0\)\(L\)处没有石子)。所有相邻的整数之间用一个空格隔开。

Output

输出只包括一个整数,表示最少踩到的石子数。

Sample Input

10
2 3 5
2 3 5 6 7

Sample Output

2

Solution

首先列出\(dp\)方程,\(f[i]\)表示到达\(i\)时最少踩到的石子数,则\(f[i]=min(f[i-k])(S\;\leq\;k\;\leq\;T)\)

然后发现数据范围是\(10^9\),所以需要状压一下。

经过思考可以发现,当\(S<T\)时,如果在\(k+\small{S\;\times\;T}\)\(k+\small{S\;\times\;T}+x(k\;\geq\;0,x>0)\)处有石子,则若存在一种方案可以越过\(k+\small{S\;\times\;T}\),那么也能越过\(k+\small{S\;\times\;T}+x\)

具体证明时把\(\small{S\;\times\;T}\)看成\(\small{T}\)\(\small{S}\)相加,易证能到达\(k+\small{S\;\times\;T}\),也能到达\(k+\small{S\;\times\;T}+x\)

所以只需将距离超过\(\small{S\;\times\;T}\)的石子距离缩到\(\small{S\;\times\;T}\)就可以了。

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M 101
#define L 20001 
using namespace std;
int a[M],f[L],l,m,s,t;
bool sto[L];
inline void init(){
    scanf("%d%d%d%d",&l,&s,&t,&m);
    for(int i=1;i<=m;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+m);
    if(s==t){
        for(int i=1;i<=m;i++)
            if(!(a[i]%s)&&a[i]<=l)
                f[0]++;
        printf("%d\n",f[0]);
        return;
    }
    for(int i=1,d;i<=m;i++){
        if(a[i]-a[i-1]>s*t){
            d=a[i]-a[i-1]-s*t;
            for(int j=i;j<=m;j++)
                a[j]-=d;
        }
        sto[a[i]]=true;
    }
    if(l-a[m]>s*t) l=a[m]+s*t;
    fill(f+1,f+1+l,M);
    for(int i=s;i<=l;i++){
        f[i]=f[i-s];
        for(int j=min(t,i);j>=s;j--)
            f[i]=min(f[i],f[i-j]);
        f[i]+=sto[i];
    }
    printf("%d\n",f[l]);
}
int main(){
    freopen("river.in","r",stdin);
    freopen("river.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout);
    return 0;
}
posted @ 2016-07-28 12:22  Aireen_Ye  阅读(256)  评论(0编辑  收藏  举报
底部 顶部 留言板 归档 标签
Der Erfolg kommt nicht zu dir, du musst auf den Erfolg zugehen.