[05NOIP improvement group] T2 crossing the river

P1052 Crossing the river

Topic portal

Idea:
Let f[i] be the minimum number of stones stepped on point i, then the value of point i can be changed from points (is) to (it) before, so we can take f[is]-f[it] In addition, if there is a stone, add 1; if there is no stone, no value is added. Here we directly use flag[i] to indicate whether there is a stone at the point (if there is one, it is 1, and if there is no, it is 0).
So we can write the state transition equation:
f [i] = min (f [i − j] + flag [i]) s <= j <= tf[i]=min(f[i−j]+flag[ i]) s<=j<=tf[i]=m i n ( f [ i - j ]+flag[i])s<=j<=t

Don’t you think it’s simple, think it’s over? Then the f array must be 10^9, it will not burst the memory-so... [I gave up this question] [Uh, is it possible] ... So we need to think according to the good tradition of NOIpN copying the original question, we I saw the doubts of Xiaokai, who had been in it for 17 years .

Path compression:
Suppose we take p or p+1 steps each time. We know that gcd(p,p+1)=1.
From the extended Euclid, we know that for the binary linear equation system:
px+(p+1)y= gcd(p,p+1) has an integer solution, that is, px+(p+1)y=s must have an integer solution.
Suppose the solution of px+(p+1)y=s is: x=x0+(p+1)t, y=y0-pt. Let 0<=x<=p (implemented by adding or subtracting t p+1), s>p*(p+1)-1, then: y = s − pxp + 1 >= s − p 2 p + 1> p ∗ (p + 1) − 1 − pxp + 1> = 0 y=\frac{s-px}{p+1}>=\frac{sp^2}{p+1}>\frac {p*(p+1)-1-px}{p+1}>=0Y=p+1s - p x>=p+1sp2>p+1p * ( p + 1 ) - 1 - p x>=0

That is to say, when s>=p*(p+1), px+(p+1)y=s has two non-negative integer solutions, each time you take p steps or p+1 steps, p∗(p+1 ) Can be reached afterwards.

If the distance between two stones is greater than p*(p+1), then you can directly change the distance between them to p*(p+1).

In summary, the method to get the compressed path: If the distance between two stones> t∗(t−1), then change their distance to t*(t-1).
Because t<=10, we can directly convert the distance greater than 10*9 to 90.
However, it should be noted that for the special case of s=t, this method is not valid. In this case, every It is impossible to take step p+1 this time, so special judgment is required.
The equation is as follows:

f[i]=f[i−1]+(i mod s ==0)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=100000000;
const int N=1e6;
int l, s, t, m, a[1100], flag[1100000], f[1000010], ans, temp;
int main()
{
    
    
	scanf("%d%d%d%d", &l, &s, &t, &m);
	for(int i=1; i<=m; i++) scanf("%d", &a[i]), ans+=(a[i]%s == 0);
	if(s == t) {
    
    printf("%d", ans); return 0;}
	sort(a+1,a+m+1);
	temp=min(l - a[m], t * (t - 1));
	l=0;
	for(int i=1; i<=m; i++)
	{
    
    
		l+=min(a[i] - a[i - 1] , t * (t - 1));
		flag[l]=1;
	}
	l+=temp;
	for(int i=1; i<=l + 9; i++)
	{
    
    
		f[i]=MAX;
		for(int j=s; j<=t; j++)
			if(i >= j) f[i]=min(f[i], f[i - j] + flag[i]);	
	} 
	ans=MAX;
	for(int i=l; i<=l + 9; i++) ans=min(ans, f[i]);
	printf("%d", ans);
	return 0;
} 

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/108156330