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\)时的最小花费

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

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

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

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

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

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

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

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=25;
  4. int f[1<<maxn],jl[1<<maxn];
  5. int jlx[maxn],jly[maxn],dis[maxn][maxn];
  6. int ans[1<<maxn],cnt;
  7. int main(){
  8. memset(f,0x3f,sizeof(f));
  9. scanf("%d%d",&jlx[0],&jly[0]);
  10. int n;
  11. scanf("%d",&n);
  12. for(int i=1;i<=n;i++){
  13. scanf("%d%d",&jlx[i],&jly[i]);
  14. }
  15. for(int i=0;i<=n;i++){
  16. for(int j=i+1;j<=n;j++){
  17. dis[i][j]=dis[j][i]=(jlx[i]-jlx[j])*(jlx[i]-jlx[j])+(jly[i]-jly[j])*(jly[i]-jly[j]);
  18. }
  19. }
  20. f[0]=0;
  21. int mmax=(1<<n)-1;
  22. for(int i=0;i<=mmax;i++){
  23. for(int j=1;j<=n;j++){
  24. if(i&(1<<(j-1))) continue;
  25. for(int k=1;k<=n;k++){
  26. if(i&(1<<(k-1))) continue;
  27. int now=i|(1<<(j-1))|(1<<(k-1));
  28. if(f[now]<=f[i]+dis[j][0]+dis[j][k]+dis[k][0]) continue;
  29. f[now]=f[i]+dis[j][0]+dis[j][k]+dis[k][0];
  30. jl[now]=i;
  31. }
  32. break;
  33. }
  34. }
  35. printf("%d\n",f[mmax]);
  36. while(mmax){
  37. printf("0 ");
  38. for(int i=1;i<=n;i++){
  39. if((mmax^jl[mmax])&(1<<((i-1)))) printf("%d ",i);
  40. }
  41. mmax=jl[mmax];
  42. }
  43. printf("0 ");
  44. return 0;
  45. }

二、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\)了

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

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=1005,maxk=21;
  4. int s[maxn],l[maxn],n;
  5. int gcd(int aa,int bb){
  6. if(bb==0) return aa;
  7. return gcd(bb,aa%bb);
  8. }
  9. int ans=0x3f3f3f3f;
  10. int tim=0;
  11. void dfs(int now,int cnt,int tot,int gys){
  12. tim++;
  13. if(tim>2e7){
  14. if(ans==0x3f3f3f3f) printf("-1\n");
  15. else printf("%d\n",ans);
  16. exit(0);
  17. }
  18. if(gys==1) ans=min(ans,tot);
  19. if(tot>=ans || cnt>9 || now>n) return;
  20. for(int i=now;i<=n;i++){
  21. if(gys==0) dfs(i+1,cnt+1,tot+s[i],l[i]);
  22. else if(l[i]%gys!=0) dfs(i+1,cnt+1,tot+s[i],gcd(gys,l[i]));
  23. }
  24. }
  25. int main(){
  26. scanf("%d",&n);
  27. for(int i=1;i<=n;i++){
  28. scanf("%d",&l[i]);
  29. }
  30. for(int i=1;i<=n;i++){
  31. scanf("%d",&s[i]);
  32. }
  33. int jud=l[1];
  34. for(int i=2;i<=n;i++){
  35. jud=gcd(jud,l[i]);
  36. }
  37. if(jud!=1){
  38. printf("-1\n");
  39. return 0;
  40. }
  41. dfs(1,0,0,0);
  42. if(ans!=0x3f3f3f3f)printf("%d\n",ans);
  43. else printf("-1\n");
  44. return 0;
  45. }

三、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

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=1e6+5;
  4. typedef long long ll;
  5. bool f[maxn];
  6. ll a[maxn];
  7. int main(){
  8. ll n,k,d;
  9. scanf("%lld%lld%lld",&n,&k,&d);
  10. for(ll i=1;i<=n;i++){
  11. scanf("%lld",&a[i]);
  12. }
  13. sort(a+1,a+1+n);
  14. f[0]=1;
  15. ll p=1;
  16. for(ll i=0;i<=n;i++){
  17. if(f[i]){
  18. p=max(p,i+k);
  19. while(p<=n && a[p]-a[i+1]<=d){
  20. f[p]=1;
  21. p++;
  22. }
  23. }
  24. }
  25. if(f[n]==0) printf("NO\n");
  26. else printf("YES\n");
  27. return 0;
  28. }

四、CF1340B Nastya and Scoreboard

题目描述

传送门

分析

比较有意思的一道题

直接放个链接题解

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=2e3+10;
  4. char num[10][10]={"1110111","0010010","1011101","1011011","0111010","1101011","1101111","1010010","11111111","1111011"};
  5. int dp[N][N];
  6. char a[N][10];
  7. int cal(char c[],int pos){
  8. int cnt=0;
  9. for(int i=0;i<7;++i){
  10. if(c[i]=='1' && num[pos][i]=='0') return -1;
  11. if(c[i]!=num[pos][i]) cnt++;
  12. }
  13. return cnt;
  14. }
  15. int main(){
  16. memset(dp,-1,sizeof(dp));
  17. int n,k;
  18. scanf("%d%d",&n,&k);
  19. for(int i=1;i<=n;++i)
  20. scanf(" %s",a[i]);
  21. for(int i=n;i>=1;--i){
  22. if(i==n){
  23. for(int j=0;j<10;++j){
  24. int t=cal(a[i],j);
  25. if(t==-1) continue;
  26. dp[n][t]=max(dp[n][t],j);
  27. }
  28. }
  29. else{
  30. for(int j=0;j<10;++j){
  31. int t=cal(a[i],j);
  32. if(t==-1) continue;
  33. for(int p=t;p<=k;++p){
  34. if(dp[i+1][p-t]!=-1){
  35. dp[i][p]=j;
  36. }
  37. }
  38. }
  39. }
  40. }
  41. if(dp[1][k]==-1){
  42. puts("-1");
  43. return 0;
  44. }
  45. int now=k;
  46. for(int i=1;i<=n;++i){
  47. printf("%d",dp[i][now]);
  48. now-=cal(a[i],dp[i][now]);
  49. }
  50. puts("");
  51. return 0;
  52. }

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. 成熟度模型:企业规模化推广敏捷和DevOps利器

    摘要: 本文介绍了成熟度模型在软件开发行业的应用,重点阐述了成熟度模型对于敏捷和DevOps在企业中进行规模化推广的价值,探讨了成熟度模型的设计原则,并对于如何明智使用成熟度模型给出了建议. 导言 在 ...

  2. Dynamics CRM Data Encrytion error

    Dynamics CRM有两个Database,一个Content DB——xxxx_MSCRM,一个Config DB——MSCRM_CONFIG. 当Content DB从其他环境Restore回 ...

  3. MYSQL 之 JDBC(九):增删改查(七)DAO的补充和重构

    DAO重构后的代码 package com.litian.jdbc; import org.apache.commons.beanutils.BeanUtils; import java.sql.*; ...

  4. python数据处理(四)之数据获取与存储

    1.前烟 几个数据问题 1.1 是否能够联系上作者本人 1.2 数据是否定期检查错误并更新 1.3 数据是否包含数据获取方法的信息,是否包含数据获取过程中使用的样本类型 1.4 有没有其他数据源可以验 ...

  5. Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁

    Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线程join.守护线程.线程互斥锁 目录 Python并发编程04 /多线程.生产消费者模型.线程进程对比.线程的方法.线 ...

  6. ASP.NET Core端点路由 作用原理

    端点路由(Endpoint Routing)最早出现在ASP.NET Core2.2,在ASP.NET Core3.0提升为一等公民. Endpoint Routing的动机 在端点路由出现之前,我们 ...

  7. C# Dictionary的底层实现解析

    引用: https://www.cnblogs.com/InCerry/p/10325290.html 字典原理分析: 1.用数组存元素,元素的结构体存hashCode.next.key.value. ...

  8. [C#]正则表达式的基本用法

    C#正则表达式的基本用法 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串.将匹配的子串替换或者从某个串中取出符合某个 ...

  9. Ant-Design-Vue中关于Table组件的使用

    1. 如何自定义表格列头: <a-table :columns="columns" :dataSource="dataSource"> <sp ...

  10. P2070 刷墙 (洛谷)

    题目描述 Farmer John已经设计了一种方法来装饰谷仓旁边的长栅栏(把栅栏认为是一根一维的线).他把一只画刷绑在他最喜爱的奶牛Bessie身上,之后就去喝一杯冰水,而Bessie隔着栅栏来回走, ...