NOIP提高组2005 过河

Posted ONION_CYC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP提高组2005 过河相关的知识,希望对你有一定的参考价值。

【算法】状态压缩型DP

【题解】

Q=tx+(t-1)y

对于Q≥t(t-1),x,y一定有解。

所以当两石子间距离long>t(t-1)时,令long=t(t-1),重新构造数组即可。

【注意】

1.输入的石子位置无序,要排序。

2.当s=t时特判。

3.最终解要在n~n+t中找最小值(不过数据太水=v=)。

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=30000,maxm=110;
int a[maxm],b[maxn],f[maxn],l,s,t,n;
int main()
{
    scanf("%d%d%d%d",&l,&s,&t,&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int ans=0;
    if(s==t)
     {
         for(int i=1;i<=n;i++)if(a[i]%s==0)ans++;
         printf("%d",ans);
         return 0;
     }
    sort(a,a+n+1);     
    int ago=0,mark=0,p=t*(t-1)+1;
    for(int i=1;i<=n;i++)
     {
         if(a[i]-ago>=p)
          b[(mark+=p)]=1;
         else b[(mark=mark+a[i]-ago)]=1;
        ago=a[i];
     }
    if(l-ago>p)
     mark+=p;
    else mark=mark+l-ago;
    memset(f,0x3f,sizeof(f));
    f[0]=0;
    for(int i=s;i<=mark;i++)
     for(int j=s;j<=t;j++)
      {
          f[i]=min(f[i],f[i-j]+b[i]);
      }
/*    for(int i=0;i<=mark;i++)printf("%d ",i);printf("\n");
    for(int i=0;i<=mark;i++)printf("%d ",b[i]);printf("\n");
    for(int i=0;i<=mark;i++)if(f[i]>1000)printf("x ");else printf("%d ",f[i]);*/
    printf("%d",f[mark]);
    return 0;
}
View Code

 

以上是关于NOIP提高组2005 过河的主要内容,如果未能解决你的问题,请参考以下文章

[NOIP2005提高组]过河

NOIP2005提高组——青蛙过河

Noip-提高组-2005-T2 过河

caioj1522: [NOIP提高组2005]过河

欧几里得算法以及扩展欧几里得算法(过河noip2005提高组第二题)

noip2005提高组 题解