P1052 过河 ( 缩点 )

中文题

想法:

那么怎么办?

我们不发现石头的数目很小

s < t时, st一定会重合(当距离为lcm(s,t)st的最小公倍数时) 而这以后的每个点都可以到达, 所以我们只需将每两个石头超过 s x t 的距离缩成s x t 就可以了

为什么可以这样缩?

因为我们关注的只是经过的石头的数目,s < t时, st一定会重合(当距离为lcm(s,t)st的最小公倍数时) 而这以后的每个点都可以到达

最后再注意特判一下 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;
}

猜你喜欢

转载自www.cnblogs.com/-Ackerman/p/12516913.html