2020河南省赛补题记录

观前提醒,本题解仅针对本人写过的题,题目思路仅供参考

若有新思路欢迎分享

B

题目描述

题目描述

题解

这道题首先要注意到\(c/d_i\)只可能有固定到可能数量,如果我们按每一集投放广告与否一遍遍遍历,时间复杂度将达到\(O(nm)\),这样是不可行的

考虑到\(n/m\)只有几种可能到取值,利用整除分块的原理我们对\(c/d_i\)所对应的值进行优化,之后我们只需要考虑对于\(c/d_i\)后可能出现的值的情况进行类似于0-1背包的枚举即可

优化后的时间复杂度是\(O(n \sqrt m)\),这样是可行的

示例代码

#include<bits/stdc++.h>
using namespace std;
void solve(){
    int n,m;
    cin>>n>>m;
    vector<int> p(n+1),d(n+1);
    for(int i=1;i<=n;i++){
        cin>>p[i];
    }
    for(int i=1;i<=n;i++){
        cin>>d[i];
    }
    vector<int> vis(m+5),val(m+5);
    int cnt = 0;
    vis[m] = 1;
    val[++cnt] = m;
    for(int i=m;i>=1;i--)
    {
        if(vis[i])
        {
            for(int j=1;j<=i;j++){
                vis[i/j]=1;
            }
            val[++cnt]=i;
        }
    }//这里对可能取到的值利用val进行压缩记录
    //防止完全遍历造成到的不必要的浪费
    vector<long long> f(m+5),g(m+5);
    for (int i = 1; i <= n; i++)
    {
        
        for (int j = 1; j <= cnt; j++)
            f[val[j] / d[i]] = max(f[val[j] / d[i]], g[val[j]] + 1LL * val[j] * p[i]);//在这一集投放广告
        for (int j = 1; j <= cnt; j++)
            g[val[j]] = f[val[j]];

        //利用g数组进行回溯,防止此处退化成类完全背包(因为实际上我们对于每一集只有两种状态,放,还是,不放)
    }
    ll ans = 0;
    for (int i = 0; i <= m; i++)
        ans = max(ans, f[i]);
    cout << ans << endl;
  
}
int main(){
    ciallo;
    ciallo1;
    int t;
    t=1;
    //cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

C

题目描述

题目描述

题解

按照题目要求模拟即可,注意\(x\)\(y\)到达\(1e8\)了,所以开long long

示例代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long dis(ll int x1, ll int y1, ll int x2, ll int y2) {
    return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
}
const int maxn = 2e3 + 10;
struct {
    ll int x, y, r;
    bool dead;
}node[maxn];
bool typ[maxn];
void solve() {
    int n; cin >> n;
    for (int i = 1; i <= n; i++) {
        int op;
        cin >> op;
        if (op == 1) {
            long long int x, y, h;
            cin >> x >> y >> h;
            node[i].x = x, node[i].y = y, node[i].r = h;
            node[i].dead = false;
            typ[i] = 1;
        }
        else if (op == 2) {
            ll int x, y, atk, r;
            cin >> x >> y >> atk >> r;
            ll int mind = LLONG_MAX, w = 0;
            for (int j = 1; j <= i; j++) {
                if (typ[j] == 1 && !node[j].dead) {
                    long long int d = dis(x, y, node[j].x, node[j].y);
                    if (typ[j] == 1 && d < mind) {
                        mind = d;
                        w = j;
                    }
                }
            }
            if (w == 0) continue;
            for (int j = 1; j <= i; j++) {
                if (typ[j] == 1 && !node[j].dead) {
                    long long int d = dis(node[w].x, node[w].y, node[j].x, node[j].y);
                    if (d <= r * r) {
                        node[j].r -= 3 * atk;
                        if (node[j].r <= 0) {
                            node[j].dead = true;
                        }
                        else {
                            node[i].dead = true;

                        }
                    }
                }

            }
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!node[i].dead) {
            cout << "Yes" << endl;
        }
        else {
            cout << "No" << endl;
        }
    }
}
int main() {
    int t;
    t = 1;
    while (t--) {
        solve();
    }
}
posted @ 2026-04-25 14:31  xiaoyintx  阅读(2)  评论(0)    收藏  举报