标签:压缩 dp vijos 过河 noip提高组2005
链接:https://www.vijos.org/p/1002
解析:
若 p*x+(p+1)*y=Q(采用跳跃距离p和p+1时可以跳至任何位置Q),则在Q ≥ P*(P-1)时是一定有解的。
由于题目给出的一个区间是1≤S≤T≤10,于是当相邻的两个石子之间的距离不小于8*9=72时,则后面的距离都可以到达,我们就可以认为它们之间的距离就是72。如此一来,我们就将原题L的范围缩小为了100*72=7200,动态规划算法完全可以承受了。
但是当S=T时,上述等式是无法使用的,在这种情况下,只需要在所有石子中,统计出坐标是S倍数的石子个数就可以了。
注意:
1.运用DP的时候,需要压缩
2.特殊解答S==T的时候
代码:
#include <istream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define MIN(x,y) (x<y?x:y) #define INF 1e7 int dp[100010]; int dd[100010]; int dis[105]; int main(){ int L,S,T,M; int i,j; scanf("%d%d%d%d", &L,&S,&T,&M); for(i=1; i<=M; ++i) scanf("%d", &dis[i]); int ans = 0; if(S==T){ for(i=1; i<M; ++i) if(dis[i]%S == 0) ++ans; } else{ dis[0] = 0; sort(dis, dis+M+1); memset(dd, 0, sizeof(dd)); for(i=1,j=0; i<=M; ++i){ if((dis[i] - dis[i-1])>100) j += 100; else j += dis[i]-dis[i-1]; dd[j] = 1; } int k = j+100; dd[0] = 0; for(i=1; i<=k; ++i){ dp[i] = INF; for(j=S; j<=T; ++j){ if(i<j) break; dp[i] = min(dp[i] , dp[i-j]+dd[i]); } } ans = dp[k]; } printf("%d\n", ans); return 0; }
Vijos P1002 过河 (NOIP提高组2005),布布扣,bubuko.com
标签:压缩 dp vijos 过河 noip提高组2005
原文地址:http://blog.csdn.net/mullerwch/article/details/35294459