Vijos 1002 过河(状态压缩)

题目链接

经典的状态压缩题目。

这个题目就是在石子特别少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 }

你可能感兴趣的:(OS)