经典的状态压缩题目。
这个题目就是在石子特别少100个,河却特别长10^9的情况下,而且跳的特别近只有1-10,有点像是省赛那个背包体积特别大的题,这种思想很重要,这个题目的代码写的很渣,思路是如果两个石子距离特别大,就可以近似的看成100,因为无论跳的能力是多少,距离很大,有很多种组合,跳不到石头上。压缩完,就按普通DP来搞就行了,注意特殊情况,特判。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <map> 6 #include <queue> 7 #include <vector> 8 #define N 10000000 9 #define ll __int64 10 using namespace std; 11 int p[20001],o[20001]; 12 ll dis[103]; 13 int main() 14 { 15 int n,i,j,s,t,len; 16 ll l; 17 scanf("%I64d",&l); 18 scanf("%d%d%d",&s,&t,&n); 19 for(i = 1; i <= n; i ++) 20 scanf("%I64d",&dis[i]); 21 dis[n+1] = l; 22 sort(dis+1,dis+n+2); 23 if(s == t) 24 { 25 j = 0; 26 for(i = 1;i <= n;i ++) 27 { 28 if(dis[i]%s == 0) 29 j ++; 30 } 31 printf("%d\n",j); 32 return 0; 33 } 34 j = 0; 35 for(i = 1; i <= n+1; i ++)//压缩 36 { 37 if(dis[i]-dis[i-1] > 100) 38 { 39 p[j+100] = 1; 40 j = j+100; 41 } 42 else 43 { 44 p[j+dis[i]-dis[i-1]] = 1; 45 j = j+dis[i]-dis[i-1]; 46 } 47 } 48 len = j; 49 p[len] = 0;//最后一个点注意一下 50 for(i = 1; i <= len+t-1; i ++) 51 { 52 int m = N; 53 for(j = s; j <= t; j ++) 54 { 55 if(i-j >= 0&&m > o[i-j]) 56 m = o[i-j]; 57 } 58 if(p[i]) 59 { 60 o[i] = m+1; 61 } 62 else 63 { 64 o[i] = m; 65 } 66 } 67 j = N; 68 for(i = len;i <= len+t-1;i ++) 69 { 70 if(j > o[i]) 71 j = o[i]; 72 } 73 printf("%d\n",j); 74 return 0; 75 }