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();
}
}

浙公网安备 33010602011771号