CF习题集三

一、CF8C Looking for Order

题目描述

\(Lena\)喜欢秩序井然的生活。一天,她要去上大学了。突然,她发现整个房间乱糟糟的——她的手提包里的物品都散落在了地上。她想把所有的物品都放回她的手提包。但是,这里有一点问题:她一次最多只能拿两个物品,她也不能移动她的手提包。并且,因为她爱整洁的习惯,如果她拿起了一个物品,她也不能将它放在其他地方,除非放回她的手提包。

\(Lena\)把她的房间划分为了一个平面直角坐标系。现在Lena给你她的手提包和每个散落的物品的坐标(当然,一开始的时候她就和手提包站在一个地方)。她从坐标 \((x1,y1)\)走到坐标 \((x2,y2)\) 需要用 \((x1-x2)^2+(y1-y2)^2\) 单位的时间。现在,\(Lena\)将告诉你她的房间的情况,请你为\(Lena\)找到一个拾起每个物品的顺序,使她拾起所有物品所需的总时间最小。当然,\(Lena\)最后需要返回她的手提包。

分析

\(n\)的范围比较小,因此我们考虑状压\(DP\)

我们设\(f[i]\)为当前拾取的物品状态为\(i\)时的最小花费

那么我们就可以写出如下的状态转移方程

f[i|(1<<(j-1))|(1<<(k-1))]=f[i]+dis[j][0]+dis[j][k]+dis[k][0];

如果单纯地这样写而不加任何优化是会\(T\)掉的

实际上,对于两个物品,我们先拿走哪一个或者后拿走哪一个对结果没有影响

因此,我们可以人为地规定一个拿取的顺序

即对于一个\(j\)一旦它匹配成功,我们就跳出循环,不再匹配

而去匹配下一个\(j\)

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=25;
int f[1<<maxn],jl[1<<maxn];
int jlx[maxn],jly[maxn],dis[maxn][maxn];
int ans[1<<maxn],cnt;
int main(){
memset(f,0x3f,sizeof(f));
scanf("%d%d",&jlx[0],&jly[0]);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&jlx[i],&jly[i]);
}
for(int i=0;i<=n;i++){
for(int j=i+1;j<=n;j++){
dis[i][j]=dis[j][i]=(jlx[i]-jlx[j])*(jlx[i]-jlx[j])+(jly[i]-jly[j])*(jly[i]-jly[j]);
}
}
f[0]=0;
int mmax=(1<<n)-1;
for(int i=0;i<=mmax;i++){
for(int j=1;j<=n;j++){
if(i&(1<<(j-1))) continue;
for(int k=1;k<=n;k++){
if(i&(1<<(k-1))) continue;
int now=i|(1<<(j-1))|(1<<(k-1));
if(f[now]<=f[i]+dis[j][0]+dis[j][k]+dis[k][0]) continue;
f[now]=f[i]+dis[j][0]+dis[j][k]+dis[k][0];
jl[now]=i;
}
break;
}
}
printf("%d\n",f[mmax]);
while(mmax){
printf("0 ");
for(int i=1;i<=n;i++){
if((mmax^jl[mmax])&(1<<((i-1)))) printf("%d ",i);
}
mmax=jl[mmax];
}
printf("0 ");
return 0;
}

二、CF510D Fox And Jumping

题目描述

给出 \(n\) 张卡片,分别有 \(l_i\)​ 和 \(c_i\)​。在一条无限长的纸带上,你可以选择花 \(c_i\)​ 的钱来购买卡片 \(i\),从此以后可以向左或向右跳 \(l_i\)​ 个单位。问你至少花多少元钱才能够跳到纸带上全部位置。若不行,输出 \(-1\)。

分析

我们先只考虑购买了两个卡片的情况

我们设这两个卡片跳跃的距离分别为\(a,b\)

其中第一张卡片使用了\(x\)次,第二张卡片使用了\(y\)次

那么跳跃的距离\(l=ax+by\)

要使方程有解,则必有\(l mod \gcd(a,b)=0\)

要使\(l\)取到任意整数,则\(\gcd(a,b)=1\)

因此,原题就变成了在\(n\)个数中选取几个数,使得这些数的最大公因数为\(1\)

求所有方案中花费最小的方案

一种可行的做法是设\(f[i]\)表示选择一些数并且最大公约数为\(i\)时的最小花费

利用\(map\)进行转移

但是现在我们考虑怎么用暴搜过掉这个题

最初始的暴搜应该比较好定义

我们传四个参数,分别是当前已经选到了第几个数、当前已经选了几个数、当前选择的所有数的价值之和、当前所有数的最大公因数

这样的暴搜不加任何剪枝会\(T\)到飞起

因此我们考虑怎么去优化

剪枝一、如果当前价值已经大于所选价值,那么就没有必要继续向下选

剪枝二、如果当前选择的数量大于9,那么就没有必要继续向下选

因为如果有\(10\)个不同的质因子,此时数会很大,已经超过了\(l[i]\)的最大值

剪枝三、提前将-1的情况预处理出来

剪枝四、如果当前枚举的\(l[i]\)是之前枚举的公因数的倍数,那么当前的\(l[i]\)一定不会使之后的公因数变小,选\(l[i]\)无意义

有了上述四个剪枝,我们已经可以跑过\(64\)个点,但是在最后一个点\(T\)了

因此,我们再加最后一个信仰剪枝,即如果当前运行次数过多,直接输出当前最优解,同时杀死程序

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1005,maxk=21;
int s[maxn],l[maxn],n;
int gcd(int aa,int bb){
if(bb==0) return aa;
return gcd(bb,aa%bb);
}
int ans=0x3f3f3f3f;
int tim=0;
void dfs(int now,int cnt,int tot,int gys){
tim++;
if(tim>2e7){
if(ans==0x3f3f3f3f) printf("-1\n");
else printf("%d\n",ans);
exit(0);
}
if(gys==1) ans=min(ans,tot);
if(tot>=ans || cnt>9 || now>n) return;
for(int i=now;i<=n;i++){
if(gys==0) dfs(i+1,cnt+1,tot+s[i],l[i]);
else if(l[i]%gys!=0) dfs(i+1,cnt+1,tot+s[i],gcd(gys,l[i]));
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&l[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&s[i]);
}
int jud=l[1];
for(int i=2;i<=n;i++){
jud=gcd(jud,l[i]);
}
if(jud!=1){
printf("-1\n");
return 0;
}
dfs(1,0,0,0);
if(ans!=0x3f3f3f3f)printf("%d\n",ans);
else printf("-1\n");
return 0;
}

三、CF985E Pencils and Boxes

题目描述

给出\(n\)个整数\(a_1,a_2,...,a_n\),现在需要对其进行分组,使其满足以下条件:

每个数都必须恰好分入一组中

每一组中必须至少包含\(k\)个数

在每一组中,整数的权值之差的绝对值不能超过\(d\)。即当\(a_i,a_j\)​在同一组时,需要满足\(|a_i+a_j| \leq d\)

请判断是否存在满足条件的分组方案,若有请输出"YES",否则输出"NO"。

数据范围:\(1 \leq k \leq n \leq 5 * 10^5 , 0 \leq d \leq 10^9\)

分析

这道题我们要用到\(bool\)类型的\(DP\)

为了方便处理,我们将所有数从小到大排一下序

我们设\(f[i]\)为当前遍历到第\(i\)个数,是否合法

其中值为\(1\)代表合法,值为\(0\)代表不合法

在转移时需要枚举每一个左端点,如果左端点的状态合法,我们再用当前的状态不断向右更新

最后如果\(f[n]\)为\(1\),那么输出YES,否则输出NO

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
bool f[maxn];
ll a[maxn];
int main(){
ll n,k,d;
scanf("%lld%lld%lld",&n,&k,&d);
for(ll i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+1+n);
f[0]=1;
ll p=1;
for(ll i=0;i<=n;i++){
if(f[i]){
p=max(p,i+k);
while(p<=n && a[p]-a[i+1]<=d){
f[p]=1;
p++;
}
}
}
if(f[n]==0) printf("NO\n");
else printf("YES\n");
return 0;
}

四、CF1340B Nastya and Scoreboard

题目描述

传送门

分析

比较有意思的一道题

直接放个链接题解

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e3+10;
char num[10][10]={"1110111","0010010","1011101","1011011","0111010","1101011","1101111","1010010","11111111","1111011"};
int dp[N][N];
char a[N][10];
int cal(char c[],int pos){
int cnt=0;
for(int i=0;i<7;++i){
if(c[i]=='1' && num[pos][i]=='0') return -1;
if(c[i]!=num[pos][i]) cnt++;
}
return cnt;
}
int main(){
memset(dp,-1,sizeof(dp));
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
scanf(" %s",a[i]);
for(int i=n;i>=1;--i){
if(i==n){
for(int j=0;j<10;++j){
int t=cal(a[i],j);
if(t==-1) continue;
dp[n][t]=max(dp[n][t],j);
}
}
else{
for(int j=0;j<10;++j){
int t=cal(a[i],j);
if(t==-1) continue;
for(int p=t;p<=k;++p){
if(dp[i+1][p-t]!=-1){
dp[i][p]=j;
}
}
}
}
}
if(dp[1][k]==-1){
puts("-1");
return 0;
}
int now=k;
for(int i=1;i<=n;++i){
printf("%d",dp[i][now]);
now-=cal(a[i],dp[i][now]);
}
puts("");
return 0;
}

CF习题集三的更多相关文章

  1. CF习题集一

    CF习题集一 一.CF915E Physical Education Lessons 题目描述 \(Alex\)高中毕业了,他现在是大学新生.虽然他学习编程,但他还是要上体育课,这对他来说完全是一个意 ...

  2. CF习题集二

    CF习题集二 一.CF507E Breaking Good 题目描述 \(Breaking Good\)这个游戏对于有经验的玩家来说也有一定的难度. 游戏的主角小明希望加入一个叫斧头帮的犯罪团伙.这个 ...

  3. 《Java练习题》习题集三

    编程合集: https://www.cnblogs.com/jssj/p/12002760.html Java总结:https://www.cnblogs.com/jssj/p/11146205.ht ...

  4. correlation filters in object tracking2

    http://www.cnblogs.com/hanhuili/p/4281077.html Correlation Filter in Visual Tracking系列二:Fast Visual ...

  5. (转)set集合的用法

    原地址:http://blog.csdn.net/chaiwenjun000/article/details/50561775 SET 集合 百度百科中说集合中的元素有三个特征: 1.确定性(集合中的 ...

  6. Correlation Filter in Visual Tracking系列二:Fast Visual Tracking via Dense Spatio-Temporal Context Learning 论文笔记

    原文再续,书接一上回.话说上一次我们讲到了Correlation Filter类 tracker的老祖宗MOSSE,那么接下来就让我们看看如何对其进一步地优化改良.这次要谈的论文是我们国内Zhang ...

  7. FZU 2087 统计树边

    这题第一直觉就是和CF第三次教育场的E题是一样的, http://codeforces.com/contest/609/problem/E 然后直接拉过来代码改了改,提交返回MLE.FZU内存开的小, ...

  8. Zookeeper 系列(五)Curator API

    Zookeeper 系列(五)Curator API 一.Curator 使用 Curator 框架中使用链式编程风格,易读性更强,使用工程方法创建连接对象使用. (1) CuratorFramewo ...

  9. 80X86指令总结

    一.数据传送指令 指令名称 汇编语句格式 功能 影响标志位 传送move data mov opd, ops (ops) → opd:分为主存储器.通用寄存器.段寄存器,不可同时使用主存储器,类型要匹 ...

随机推荐

  1. CSS 的层叠上下文是什么

    层叠上下文是 HTML 中的一个三维的概念,每个层叠上下文中都有一套元素的层叠排列顺序.页面根元素天生具有层叠上下文,所以整个页面处于一个“层叠结界”中. 层叠上下文的创建: 页面根元素:html z ...

  2. 007.Nginx虚拟主机

    一 虚拟主机 1.1 虚拟主机概念 对于Nginx而言,每一个虚拟主机相当于一个在同一台服务器中却相互独立的站点,从而实现一台主机对外提供多个 web 服务,每个虚拟主机之间是独立的,互不影响的. 1 ...

  3. JavaScript学习 Ⅵ (正则表达式)

    十三. 正则表达式 正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式,来检查一个字符串是否符合规则,将字符串中符合规则的内容提取出来. 创建正则表达式对象 构造函数 var reg = n ...

  4. javascript基础(七):js发送请求

    GET请求 $.get("/api/v1.0/user",function(resp){ // 用户未登录 if ("4101" == resp.errno) ...

  5. 数据可视化之powerBI技巧(十八)Power BI动态技巧:动态显示列和度量值

    今天分享一个可视化小技巧,如何在PowerBI的表格中动态显示需要的列? 就是这样的效果, 也就是根据切片器的筛选,来显示需要的列,做起来很简单,步骤如下: 01 逆透视表 进入Powerquery编 ...

  6. js 声明变量规范和特殊变量情况

    声明变量特殊情况    情况 说明 结果 var age ; console.log (name); 只声明 不赋值 undefined console.log(name) 不声明 不赋值  直接使用 ...

  7. 纯 CSS 实现滑动轮播图效果

    只使用css实现轮播图简单的操作 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  8. [Cordova]Cordova6.x自定义插件之Andorid

    1.继承了CordovaPlugin的Java Class 需要重写execute方法,如下: 2.在res/xml/config.xml中关联上述java class 3.在assets/www/p ...

  9. OSCP Learning Notes - Exploit(5)

    Java Applet Attacks Download virtual machines from the following website: https://developer.microsof ...

  10. final总结

    final 1.类 不含任何子类,有父类(太监类):其中方法不能覆盖重写. 2.方法 最终方法,不能被覆盖重写. 3.局部变量 赋值后不能改变,只能赋一次值. 4.成员变量 <1>由于成员 ...