P1052 river (condensing point)

Chinese title

 

idea:

 

So how do?

We do not find that the number of small stones

s <time t,  S and t will overlap (when the distance is LCM (s, t) i.e. S , t least common multiple of the time) of each point can be reached after this, so we just each two stone more than  sxt  distance shrunk sxt  on it

Why can this reduction?

Because the number of stones only after we are concerned, s <time t,  S and t will coincide (when the distance is lcm (s, t) that is S , t the least common multiple of the time) and that after each point can Arrivals

 

Finally, special attention judgment about when s == t

 

#pragma GCC optimize(3,"Ofast","inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>
#include <cstring>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f

const double eps = 1e-10;
const int maxn = 2e5 + 10;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

int f[maxn];
int stone[maxn],new_stone[maxn],vis[maxn];

int main() {
    ios::sync_with_stdio(false);
    int L;
    cin >> L;
    int l,r,n;
    cin >> l >> r >> n;
    if (l == r) {
        int cnt = 0;
        for (int i = 1;i <= n;i++) {
            cin >> stone[i];
            if (stone[i] % l == 0)
                cnt++;
        }
        cout << cnt << endl;
        return 0;
    }
    for (int i = 1;i <= n;i++)
        cin >> stone[i];
    sort(stone+1,stone+1+n);
    int p = l * r;
    for (int i = 1;i <= n;i++) {
        int d = stone[i] - stone[i-1];
        if (d >= p)
            d = p;
        new_stone[i] = new_stone[i-1] + d;
        vis[new_stone[i]] = 1;
    }
    L = new_stone[n] + p;
    memset(f,0x3f,sizeof(f));
    f[0] = 0;
    for (int i = 1;i <= L;i++) {
        for (int j = l;j <= r;j++) {
            if (i >= j) {
                if (vis[i])
                    f[i] = min(f[i],f[i-j]+1);
                else
                    f[i] = min(f[i],f[i-j]);
            }
        }
    }
    int ans = INF;
    for (int i = new_stone[n];i <= L;i++)
        ans = min(ans,f[i]);
    cout << ans << endl;
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/-Ackerman/p/12516913.html