Vijos 1002 过河(状态压缩)

题目链接

经典的状态压缩题目。

这个题目就是在石子特别少100个,河却特别长10^9的情况下,而且跳的特别近只有1-10,有点像是省赛那个背包体积特别大的题,这种思想很重要,这个题目的代码写的很渣,思路是如果两个石子距离特别大,就可以近似的看成100,因为无论跳的能力是多少,距离很大,有很多种组合,跳不到石头上。压缩完,就按普通DP来搞就行了,注意特殊情况,特判。

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 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 }

转载于:https://www.cnblogs.com/naix-x/archive/2012/10/10/2718618.html

你可能感兴趣的:(Vijos 1002 过河(状态压缩))