题意:一条长度为L(L <= 1e9)的桥上有N(1<= N <= 100)颗石头。桥的起点为0终点为L.一只青蛙从0开始跳,每次跳的长度在s,t(1<= s <= t <= 10)之间。问青蛙过河最少踩到的石头的数量?
思路:区间dp的感觉很强烈。。但是范围实在是太大了。并且有一种感觉就是当两颗相邻的石头之间的距离相距很远时,其中间的很大一段其实状态只是一个递推的关系,即只是传递,并没有改变一段区间的状态。并且有数学公式的支持;
p*x + (p+1)*y = Q;其中p,p+1表示跳跃的距离,x,y分别表示对于跳跃距离的次数;
当Q >= p(p-1)时,从该起点到Q之后的每一个点都能到达。证明很简单,只需要通过mod就可以得出x,y的取值;
这样直接特判s = t的情况,之后离散化距离;
当a[i] - a[i-1] >= 90(原本应该是72的,但是wa了一点...),直接mod 90即可;
被各种初始化...WA了;
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> #include<map> #include<queue> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define inf 0x3f3f3f3f #define lson l, m, rt << 1 #define rson m+1, r, rt << 1|1 typedef pair<int,int> PII; #define A first #define B second #define MK make_pair typedef __int64 ll; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } int T,kase = 1,i,j,k,n,m; int dp[10000],a[107],p[10000],tmp[107]; int main() { MSi(dp); int l,s,t; read1(l); read3(s,t,m); rep1(i,1,m) read1(a[i]); if(s == t){ int ans = 0; rep1(i,1,m) if(a[i]%s == 0) ans++; printf("%d ",ans); return 0; } sort(a,a+m+1); a[0] = 0,a[++m] = l; rep1(i,1,m){ tmp[i] = tmp[i-1] + (a[i] - a[i-1])%90;//递推实现离散化距离 p[tmp[i]] = 1; } rep1(i,s,t) dp[i] = p[i]; rep1(i,2*s,tmp[m]){ //这边从2*s开始 int L = max(i-t,0), r = i - s; rep1(j,L,r) dp[i] = min(dp[i],dp[j]); if(p[i]) dp[i]++; } printf("%d ",dp[tmp[m]]-1);//设置了L处也有石头 return 0; }