代码改变世界

过河

2019-04-10 20:48  一只弱鸡丶  阅读(179)  评论(0)    收藏  举报

题目传送门

递推式很容易想得到  f[i]=min(f[i-j]+当前点是否有石头,f[i])

直接DP +一些特判估计能骗50%吧。题目开的100%数据L为10^9,那以这样的转移方程肯定爆炸。

但是最后看了下题解发现还是用这个转移式,只不过要路径压缩(本蒟蒻不会,看了下题解里Panda_hu 大佬 终于懂了)

只要把相隔大于90的石头做一下路径压缩就行了,之后把总长度修改一下就OK了

为什么可以这样呢?

    当S!=T时,任意步数p,p+1,肯定互质。。。然后gcd(p,p+1)=1,那么大于p*(p+1)的点在后面肯定也跑得了。那么就有下面代码。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
using namespace std;
#define ll long long
#define re register
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define P pair<int,int>
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch-'0';
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=a*10+ch-'0';
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
int f[10005],a[10005],b[10005],c[10005];///f[i]为在i位置踩石头最小的数
bool book[10005];
int main()
{
    int L;
    read(L);
    int S,T,M;
    read(S);
    read(T);
    read(M);
    if(S==T)
    {
        int ans=0;
        for(re int i=1;i<=M;i++)
        {
            int x;
            read(x);
            if(x%S==0)
                ans++;
        }
        return write(ans),0;
    }
    for(re int i=1;i<=M;i++)
        read(a[i]);
    sort(a+1,a+M+1);///不排序会RE!!!
    memset(f,0x3f,sizeof(f));
    a[0]=0,f[0]=0;
    c[M+1]=min(L-a[M],91);///最后一个石头与终点的最短距离,压缩
    L=0;
    for(re int i=1;i<=M;i++)///压缩路径
        b[i]=min(a[i]-a[i-1],90),L+=b[i],book[L]=1;
    L+=c[M+1];
    for(re int i=S;i<=L+10;i++)///从S开始的原因是因为i<S时都跳过去了,f[i]肯定为0
        for(re int j=S;j<=T;j++)
            f[i]=min(f[i],f[i-j]+(book[i]==1));///当前点与上一级跳过来的点+1做转移,这个转移方程应该很简单。
    int ans=0x3fffffff;
    for(re int i=L;i<=L+10;i++)
        ans=min(f[i],ans);
    write(ans);
    return 0;
}
View Code