E

解题思路

这题求的是满足\(\sum^n_{i=1}(|x-x_i|+|y-y_i|)\leq D\) 的坐标\((x,y)\) 的数目,由于是求和,所以\(x,y\) 之间是相互独立的

  • 第一步,先分别求出满足\(\sum^n_{i=1}|x-x_i|\leq D\) 和\(\sum^n_{i=1}|y-y_i|\leq D\) 的\(sum_x\)和\(sum_y\),这两者是等价的
  • 第二步,对第一步求出的结果排序,枚举\(sum_x\),然后用二分或者双指针去求满足的\(sum_y\)的数量,累计即为答案

对于第一步,先对数组\(x\)进行排序,注意到\(x\)的范围仅为\([-10^6,10^6]\),\(D \leq 10^6\),所以我们可以从\(min\_x-10^6\)枚举到\(max\_x+10^6\),枚举出符合\(sum_x\leq D\)的\(sum_x\),最开始求一遍\(sum_x\),后面枚举时对\(sum_x\)动态维护即可

代码

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
using pii = pair<int, int>;
using piii = pair<int, pii>;
using pll=pair<ll,ll>;
using plll=pair<ll,pii>;
#define fi first
#define se second
const int INF = 0x3f3f3f3f; void solve() {
int n,d;
cin>>n>>d;
vector<int> a(n),b(n);
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
auto get=[&](vector<int>&a){
vector<int> res;
sort(a.begin(),a.end());
if(a.back()-a.front()>d) return res;//没啥用的剪枝
int st=a.front()-d;
ll sum=0;
for(int i=0;i<n;i++) sum+=abs(a[i]-st);
bool tag=false;
int cnt=0;
for(int i=st;i<=a.back()+d;i++){
if(sum<=d) res.push_back(sum);
if(sum<=d) tag=true;//没啥用的剪枝
if(tag&&sum>d) break;//没啥用的剪枝
while(cnt<n&&i==a[cnt]) cnt++;
sum+=cnt-(n-cnt);
}
sort(res.begin(),res.end());
return res;
};
vector<int> xs=get(a),ys=get(b);
ll ans=0; for(int i=0,j=ys.size()-1;i<xs.size();i++){//双指针
while(j>=0&&ys[j]+xs[i]>d) j--;
ans+=j+1;
}
cout<<ans<<endl;
} int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}

F

解题思路

我们先把选的组合固定,必然选的组合长度为\(K\),下面就要考虑组合的顺序

对于\(A_i,B_i,A_{i+1},B_{i+1}\),假设第\(i\)在前,结果为\(A_{i+1}*(A_i*x+B_i)+B_{i+1}\),即为\(A_iA_{i+1}*x+A_{i+1}B_i+B_{i+1}\),假设第\(i+1\)在前,结果为\(A_iA_{i+1}*x+A_iB_{i+1}+B_i\),如果前者顺序由于后者的顺序,那么前者式子大于后者,化简得\((A_{i+1}-1)*B_i>(A_i-1)*B_{i+1}\),按这样的优先级对数对进行排序,从前往后顺序选一定是最优的

顺序确定了,考虑选那些数对,我们定义\(dp[i][j]\)为前\(i\)个数对选了\(j\)个数对时的最大值,并用滚动数组优化为一维(类似01背包),转移方程见代码

代码

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
using ll = long long;
using pii = pair<int, int>;
using piii = pair<int, pii>;
using pll=pair<ll,ll>;
using plll=pair<ll,pii>;
#define fi first
#define se second
const int INF = 0x3f3f3f3f; void solve() {
int n,k;
cin>>n>>k;
vector<pii> tup(n);
for(int i=0;i<n;i++){
auto &[a,b]=tup[i];
cin>>a>>b;
}
sort(tup.begin(),tup.end(),[&](pii A,pii B){
return (A.fi-1)*B.se<(B.fi-1)*A.se;
});
vector<ll> dp(k+1);
dp[0]=1;
for(int i=0;i<n;i++){
for(int j=k-1;j>=0;j--){
if(dp[j])
dp[j+1]=max(dp[j+1],dp[j]*tup[i].fi+tup[i].se);
}
}
cout<<dp[k]<<endl;
} int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int _ = 1;
// cin >> _;
while (_--) {
solve();
}
return 0;
}

随机推荐

  1. Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?

    目录 Elasticsearch聚合查询说明 空值率查询DSL Elasticsearch聚合基础知识扩展 Elasticsearch聚合概念 Script 用法 Elasticsearch聚合查询语 ...

  2. 行为型模式(Behavioer Pattern)

    行为型设计模式 行为型模式定义了系统中对象之间的交互与通信,研究系统在运行时对象之间的相互通信与协作,进一步明确对象的职责,包括对系统中较为复杂的流程的控制. 在软件系统运行时对象并不是孤立存在的,它 ...

  3. CAP 8.2 版本发布通告

    前言 今天我们很高兴宣布 CAP 发布 8.2 版本正式版,我们在这个版本中主要致力于对订阅着并行执行的特性提供支持,同时添加了对在订阅者中对消息头的控制行为. 下面,具体看一下我们新版本的功能吧. ...

  4. arm linux 移植 curl

    背景 libcurl是一个跨平台的开源网络协议库,支持http, https, rtsp等多种协议 .libcurl同样支持HTTPS证书授权,HTTP POST, HTTP PUT, FTP 上传, ...

  5. Ubuntu下的NVIDIA显卡【安装与卸载、CUDA安装】

    @ 目录 0. 显卡GPU的基础知识 1. 显卡安装 Optional: 卸载显卡(当你要换显卡的时候) 2. 安装CUDA 碎碎念:主要是把显卡相关的整合出来,基础知识后面再放上来 显卡安装后可以有 ...

  6. Canavs在文字上绘制删除线/中划线

    效果图: 思路: 绘制文字 绘制高度为1px的长方形,并用黑色填充 长方形的宽度为文字的长度 具体代码: let canvas = document.getElementById('canvas'); ...

  7. Java 对象转XML xStream 别名的使用 附下载方式

    下载方式 Maven方式 pom.xml中 <dependency> <groupId>xstream</groupId> <artifactId>xs ...

  8. 修改Jenkins默认管理员admin密码

    1.删除Jenkins目录下config.xml文件中下面代码,并保存文件. <useSecurity>true</useSecurity><authorizationS ...

  9. 【算法】用c#实现自定义字符串编码及围栏解码方法

    编写一个函数/方法,它接受2个参数.一个字符串和轨道数,并返回ENCODED字符串. 编写第二个函数/方法,它接受2个参数.一个编码字符串和轨道数,并返回DECODED字符串. 然后使用围栏密码对其进 ...

  10. git http(s) 保存用户密码

    git 常用配置 git记住密码 1.设置记住密码(默认15分钟): git config --global credential.helper cache 2.如果想自己设置时间,可以这样做: gi ...