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. Hibernate Validator 校验注解

    Hibernate Validator 校验注解/** * 认识一些校验注解Hibernate Validator * * @NotNull 值不能为空 * @Null 值必须为空 * @Patter ...

  2. spring boot jpa 进行通用多条件动态查询和更新 接口

    原因: jpa 没有类似于mybatis的那种 拼接sql的方式 想动态更新 需要使用 CriteriaUpdate的方式 去一直拼接,其实大多数场景只要传入一个非空实体类,去动态拼接sql 1.定义 ...

  3. 2024年软件架构趋势之AI与机器学习的关系

    在当下这个信息爆炸的时代,我们经常会听到"AI"和"机器学习"这两个词.它们似乎总是携手出现,让人觉得它们就是一对不可分割的"好基友".但你 ...

  4. Nginx SSL证书更新及密码套件更新

    一.域名更换证书 ssl证书一般包括证书文件crt.cer.pem.pfx和私钥文件key. CER.CRT.PEM 和 PFX 是不同的证书文件格式,它们之间存在一些区别: CER (DER 编码) ...

  5. Kubernetes(四)Pod详解

    Pod详解 本章主要介绍Pod资源的各种配置(yaml文件)和原理 1. Pod介绍 如上图所示,每个Pod中都可以包含一个或多个Container,这些Containers 可以分为2类: 用户程序 ...

  6. Sql Server 创建用户并限制权限

    创建登录名 使用sa或者Windows身份验证登录,[安全性]-[登录名],右键[新建登录名] 设置登录名属性 设置数据库权限 db owner --拥有数据库全部权限,包括删除数据库权限 db ac ...

  7. jsbarcode 生成条形码,并将生成的条码保存至本地,附源码

    导读 以前生成条码都是外网网站上生成,因生产环境在内网中,上不了外网,只能在项目中生成相应规则,故将此方法整理下来. html <!DOCTYPE html> <html> & ...

  8. C#-WPF初学

    1.新建一个WPF的应用: 2.拖拽控件并布局好: [小技巧]选中控件,点击"回形针"即可让该控件跟随窗口自动调整大小: 3.编写代码: 主程序代码如下: namespace Wp ...

  9. Azure Function 时区设置

    一,引言 Azure Function 上的默认使用UTC 运行程序,我们在获取时间,或者通过时间执行某些逻辑时,返回UTC 时间,导致业务数据不正常,由于 Azure Function 是微软提供的 ...

  10. oeasy教您玩转vim - 61- # 编辑过程

    ​ 编辑过程 回忆上次 vi可以加各种参数 vi +4 oeasy.txt vi +/shiyanlou vi +%s/shiyanlou/oeasy/g oeasy.txt vi可以接收stdin的 ...