This problem is NOIP first DP optimization problem, seemingly easy, actually want full score also quite difficult.
Portal:1002 River Crossing
Algorithm
It is obvious that the DP,DP equation should be used in this question:
if (Stone[i]) f[i]=min{f[i-j]}+1; (s<=j<=t)
else F[i]=min{f[i-j]};
The time complexity is O (LT) and the spatial complexity is O (L) .
And this problem of L up to 1 billion , so this simple method can only get 30 points , obviously cannot ac.
Optimization
1. Scrolling an array
According to the DP equation we derive, the state transfer requires only the value of f[i-t]~f[i-s] , so only a scrolling array of size T is required.
So the spatial complexity is optimized to O (T) . Since t is less than or equal to 10, there is obviously no problem on the space.
2. Discretization of DP
Look at other people's solution, found that some people choose to press 105 to optimize, although this method can be, but more or less opportunistic suspects, after all, when the game who know to press exactly 105?
So we have to come up with a general approach. We will find that the number of stones m is far less than the length of L, can not help but let us think of discretization-when s<t and there is a large segment of the bridge is not a stone, often will appear the entire rolling array f value of the same situation, when we encounter the next stone no longer change the value of F, so as to achieve optimal results.
Use the tot variable to record the number of consecutive occurrences of the current value, if more than T, then jump directly to the position of the next stone, thereby increasing efficiency.
After optimization, the time complexity drops to O (MT) , which has reached the AC requirement.
Special Award
The above discretization is obviously based on the s<t. If s==t, then never reach the optimization conditions, optimization will not work, thus *tle:90 points * .
So we have to add a special sentence, when s==t, ans is the number of stones where the position is a multiple of T. Though simple, it is a test of the rigor of the player's thinking.
Code:
#include <cstdio> #include <cstring> #include <algorithm> #define INF 0x3f3f3f3fusing namespace std; int dp[100];int r[200];inline int min (int a,int b) {return a<b?a:b;} int main () {int l,s,e,m; scanf ("%d%d%d%d", &l,&s,&e,&m); for (int i=0;i<m;i++) scanf ("%d", r+i); Sort (r,r+m); memset (dp,inf,sizeof DP); int p=0,tot=0,now=0; dp[0]=0; if (s==e) {int ans=0; for (int i=0;i<m;i++) if (r[i]%e==0) ans++; printf ("%d\n", ans); return 0; } for (int i=1;i<=l;i++) {for (int j=s;j<=e;j++) {dp[i%e]=min (dp[i%e],dp[(i-j+e)%e]); Scrolling array, subscript 0-(T-1)} if (I==r[p])//record whether there is a stone, think with vis mark, really too funny! {dp[i%e]++; p++; } if (now==dp[i%e])//away from tot++; else {now=dp[i%e]; tot=0; hash} if (tot==e) {i+= (min (r[p]-e,l)-i)/e*e; }//} printf ("%d\n", dp[l%e]); return 0;}
Vijos 1002 River crossing [monotone DP, rolling array, discretization]