vijos p1002 dp ***

链接:点我

一开始的方程式很好写的,但是数据太大,考虑到石子数目很小,我们对其进行离散化,若相邻两点距离超过ya的值,则后面所有点都往前移动,这里ya的值是可以调整的

#include <iostream>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxn=110;

const int maxdp=100001;

const int inf=100000000;

const int ya=75;

int len,s,t,n;

int cnt=0;

int a[maxn],dp[maxdp],v[maxdp];

int cmp(int x,int y)

{

    return x<y;

}

int main()

{

    cin>>len>>s>>t>>n;

    for(int i=1;i<=n;i++) cin>>a[i];

    a[n+1]=len;    a[0]=0;

    if(s==t)

    {

        for(int i=1;i<=n;i++)

            if(a[i]%s==0) cnt++;

        cout<<cnt;

        return 0;

    }

    sort(a+1,a+n+1,cmp);

    for(int i=1;i<=n+1;i++)

      if(a[i]-a[i-1]>ya)

      {

          int t=a[i]-a[i-1]-ya;

          for(int j=i;j<=n+1;j++) a[j]=a[j]-t;

      }

    memset(v,0,sizeof(v));

    for(int i=1;i<=n;i++) v[a[i]]=1;

    len=a[n+1];

    for(int i=0;i<maxdp;i++) dp[i]=inf;

    dp[0]=0;

    for(int i=1;i<=len;i++)

      for(int j=i-t;j<=i-s;j++)

          if(j>=0)

          dp[i]=min(dp[i],dp[j]+v[i]);

    cout<<dp[len];

    return 0;

}

 

你可能感兴趣的:(OS)