第三题:教主的别墅(villa)

(villa.pas/cpp/in/out)

villa.in

villa.out

【题目背景】

  LHX教主身为宇宙第一富翁,拥有一栋富丽堂皇的别墅,由于别墅实在太大了,于是教主雇佣了许许多多的人来负责别墅的卫生工作,我们不妨称这些人为LHXee。

【题目描述】

  教主一共雇佣了N个LHXee,这些LHXee有男有女。

  教主的大别墅一共有M个房间,现在所有的LHXee在教主面前排成了一排。教主要把N个LHXee分成恰好M个部分,每个部分在队列中都是连续的一段,然后分别去打扫M个房间。

  教主身为全世界知识最渊博的人,他当然知道男女搭配干活不累的道理,以及狼多羊少,羊多狼少的危害之大。所以教主希望一个分配方式,使得所有小组男女个数差的最大值最小。

教主还希望你输出从左到右,每个组的人数。

  如果有多种人数组合都能达到最优值,教主希望你分别告诉他这些方案中字典序最小和最大的方案。换句话说,你需要找到两种方案,这两种方案满足所有组男女个数差最大值最小的前提下,第一种方案(字典序最小)要越靠前的组人数越少,也就是让第一个小组人尽量少,并且在第一个小组人尽量少的前提下,让第二个小组的人尽量少,依此类推;第二种方案(字典序最大)则要让越靠前的组人数越多。

【输入格式】

  输入的第1行为两个正整数N与M,用空格分隔。

  第2行包含一个长度为N的串,仅由字符组成,第i 个字符为0表示在这个位置上的LHXee为女生,若为1则为男生。

【输出格式】

输出文件包含两行,每行M个正整数,正整数之间用空格隔开,行末无多余空格。这M个正整数从左到右描述了你所分的每个组的人数。

第1行为字典序最小的方案,第2行为字典序最大的方案。

【样例输入】

8 3

11001100

【样例输出】

1 2 5

5 2 1

【样例说明】

字典序最小的方案按1, 10, 01100分组,每组男女个数差的最大值为1,为最小。

字典序最大的方案按11001, 10, 0分组。

【数据规模】

对于40%的数据,有N ≤ 100;

对于50%的数据,有N ≤ 1000;

对于65%的数据,有N ≤ 100000;

对于100%的数据,有N ≤ 5000000,M ≤ N且M ≤ 100000。

【提示】

关于字典序:

比较S1[N]与S2[N]的字典序大小,可以找到S1[N]与S2[N]中第1个不相同数字S1[i]与S2[i](即有对于所有1≤k<i,都有S1[k] =S2[k],但S1[i]≠S2[i])。如果S1[i]<S2[i],那么说S1[N]字典序比S2[N]小,否则说S1[N]字典序比S2[N]大。

第一眼:二分,转化判定性问题

于是就慢慢慢慢分,写个dfs分吧~~~

然后再看:求出答案

这tm怎么求啊!!!!

于是慢慢慢慢求,写两个dfs吧~~~

果断T掉,还好有个35分不错了

我的Code:

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/
#define for0(i,j) for(int i=0;i<j;i++)
#define for1(i,j) for(int i=1;i<=j;i++)
#define clear(arr,x) memset(arr,x,sizeof(arr))
/
int n,m;
int sum1[5000005]={0};
char a[5000001];int ans1[100001],ans2[100001];
int cnt1=0,cnt2=0;
int num0=0;
namespace LCT
{         //};        //
/
void qin(int &ret)
{char c;ret=0;while((c=getchar())<'0'||c>'9');while(c>='0'&&c<='9')ret=ret*10+c-'0',c=getchar();
}bool check(int s,int m,int cut)
{if(cut==1){if(abs(sum1[n]-sum1[s])<=m)return 1;else return 0;}for(int i=s+1;i<=n-cut+1;i++){if(abs(sum1[i]-sum1[s])<=m&&check(i,m,cut-1)) return 1;}return 0;
}
bool dfs1(int s,int m,int cut)
{if(cut==1){if(abs(sum1[n]-sum1[s])<=m){ans1[++cnt1]=n-s;for(int i=1;i<=cnt1;i++) printf("%d ",ans1[i]);return 1;}else return 0;}for(int i=s+1;i<=n-cut+1;i++){ans1[++cnt1]=i-s;if(abs(sum1[i]-sum1[s])<=m&&dfs1(i,m,cut-1)){return 1;}cnt1--;}return 0;
}
bool dfs2(int s,int m,int cut)
{if(cut==1){if(abs(sum1[n]-sum1[s])<=m){ans2[++cnt2]=n-s;for(int i=1;i<=cnt2;i++) printf("%d ",ans2[i]);return 1;}else return 0;}for(int i=n-cut+1;i>=s+1;i--){ans2[++cnt2]=i-s;if(abs(sum1[i]-sum1[s])<=m&&dfs2(i,m,cut-1)){return 1;}cnt2--;}return 0;
}
/
void input()
{qin(n); qin(m);// getchar();for1(i,n){a[i]=getchar()=='0'?-1:1;sum1[i]=sum1[i-1]+a[i];if(sum1[i]==0)num0++;}
}
void solve()
{///init///int l=0,r=n/m+1,mid;int ans;calculate//if(num0>=m)r=0;while(l<r){mid=(l+r)>>1;if(check(0,mid,m)) r=mid;else              l=mid+1;}ans=l;l=1,r=1;dfs1(0,ans,m);puts("");//for1(i,n)printf("%d ",sum2[i]);dfs2(0,ans,m);/output//*puts("");for(int i=cnt2;i>=1;i--) printf("%d ",ans2[i]);*/
}
/
int main()
{#ifndef _TESTfreopen("villa.in","r",stdin); freopen("villa.out","w",stdout);#endifinput();solve();#ifdef _TESTfor(;;);#endifreturn 0;
}

这题尼玛用贪心、、咳咳、、、、

能贪个什么东西啊、、、

据网上神犇所说“易证:最优方案下,最大男女人数差ans=(abs(a[n])-1)/m+1(即上取整)”

AC Code~~~

最近是dev的tab出问题了吗?缩进成了这样、、、

//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/
#define for0(i,j) for(int i=0;i<j;i++)
#define for1(i,j) for(int i=1;i<=j;i++)
#define clear(arr,x) memset(arr,x,sizeof(arr))
/
const int maxn=5000000+10;
int n,m;
char s[maxn];
int dif[maxn];
int zero,ans,mis;
int st[maxn];
/
inline int abs(int x){return x>0?x:-x;}
void cal()//按每组人数字典序最小原则分组
{zero=0,mis=0;memset(dif,0,sizeof(dif));for(int i=0;i<n;i++){if(s[i]=='1')mis++;else mis--;dif[i]=mis;if(!mis)zero++; }if(!dif[n-1] && zero>=m){if(zero>=m)ans=0;else ans=1;}else ans=abs(abs(dif[n-1])-1)/m+1;int cnt=0,cur=-1;for(int i=0;i<n;i++){if(cnt>=m-1)//如果已经分了m-1组了,则将后面n-i人作为第m组就完工了 {st[cnt++]=n-i;break;} if(abs(dif[n-1]-dif[i])<=ans*(m-cnt-1))//后n-i人的男女差 = 总男女差 - 前面i人的男女差 <= 后m-cnt组*ans ,则可以按此分组                {st[cnt++]=i-cur;//将[cur+1,i]分为一组 cur=i;}}
}
/*void cal()
{  int cnt=0,cur=-1;  zero=0,mis=0;  clear(dif,0);  for0(i,n)  {  if(s[i]=='1') mis++;  else          mis--;  dif[i]=mis;  if(!mis)zero++;  }  if(!dif[n-1]&&zero>=m) ans=0;  else                   ans=abs(abs(dif[n-1])-1)/m+1;  for0(i,n)  {  if(cnt>=m-1)  {  st[cnt++]=n-i;  break;  }  if(abs(dif[n-1]-dif[i])<=ans*(m-cnt+1))  {  st[cnt++]=i-cur;  cur=i;  }  }
}  */
/
void input()
{  scanf("%d%d\n",&n,&m);  gets(s);
}
void solve()
{  ///init///  calculate  cal();  for0(i,m) printf("%d ",st[i]);  puts("");  reverse(&s[0],&s[n]);  cal();  for0(i,m) printf("%d ",st[m-i-1]);  /output/  }
/
int main()
{  #ifndef _TEST  freopen("villa.in","r",stdin); freopen("villa.out","w",stdout);  #endif  input();  solve();  #ifdef _TEST  for(;;);  #endif  return 0;
}

教主的别墅(villa)相关推荐

  1. 【jzoj】2018.2.7NOIP普及组——某【BC】组模拟赛

    前言 --终于改完了,像之前小L一样崩溃.今天C组和B组一起做题,所以-- 正题 题目1:教主的花园(jzoj1792) 一平面直角坐标系,在x轴的位置建立一堵墙,墙上有n道门,给出门的位置,询问两个 ...

  2. 中西造园水法浅比【ZZ】

    中西造园水法浅比 ( 2005-06-23      出自: <中国园林> ) 1 中西造园水法历史比较  水在我国早期庭园构成上就占据主要地位,主要表现在两个方面:(1)水体形式丰富,景 ...

  3. 纪中国庆10.5做题小结

    纪中国庆10.5做题小结 T1:教主的花园 T2:教主泡嫦娥 T3:保镖排队 T4:教主的别墅 T1:教主的花园 Description [问题背景] LHX教主最近总困扰于前来膜拜他的人太多了,所以 ...

  4. jzojNOIP2014模拟 8.14总结

    教主的花园 (Standard IO) Time Limits: 1000 ms  Memory Limits: 65536KB Goto ProblemSet Description [问题背景] ...

  5. 英汉互译教程---生词

    indefinite 无限期的,无限期的: 不明确的,模糊的: 模糊的: [语]不定的 We must accept finite disappointment, but we must never ...

  6. 美国英语与英国英语的区别(二)

    美国英语与英国英语在词汇.语法.拼法.读音和其它等方面存在着许多差异. 1.词汇方面的差异 美国英语所特有的词汇和短语可分为三类:第一类是美国人创造的新词,如movie(电影).bootlegger( ...

  7. c++win32项目 如何显示后再删除一个绘图_【AC学习】当乐高遇上BIM(7):绘图中的数据展示...

    介绍 正如在之前文章中提到,我们可以将数据加入3D模型以创建建筑信息建模(BIM).这些数据被嵌入进了模型的不同位置,比如项目.场地.建筑.楼层(建筑楼层).空间.区域.组件/构件.类型和系统.我们会 ...

  8. 二手房源信息数据分析与可视化

    数据读取及描述性分析,得到房价及平米的数值型描述 删除车位信息 数据分析1:价格最高的5个别墅,删除别墅信息 数据分析2:找出数据中的住房户型分布 数据分析3:找出关注人数最多的五套房子 数据分析4: ...

  9. UVa 321 The New Villa,2B青年怒找卧室

    题目链接: UVA : http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24 ...

最新文章

  1. Python极简入门:数据类型、条件语句、循环语句、异常处理
  2. 第三章 Redis/SSDB+Twemproxy安装与使用
  3. 关于uint8_t/uint16_t/uint32_t/uint_fast16_t
  4. linux内核镜像sd卡,【原创】Linux QT镜像的制作--制作SD卡启动盘
  5. App安全之网络传输安全
  6. Docker容器虚拟化技术---Docker运维管理(Swarm集群管理)3
  7. java子类代码块_java中父类子类静态代码块、构造代码块执行顺序
  8. html 3d坐标,HTML3D
  9. 《计算机操作系统》大作业【参考代码解读】
  10. python模块基础之OS模块
  11. 阿里中间件首席架构师钟华:《企业IT架构转型之道:阿里巴巴中台战略思想与架构实战》新书出版(含试读PDF)!...
  12. 模拟游戏--鸭子的种类
  13. Istio学习笔记-熔断实验
  14. wiz为知笔记docker部署与数据迁移
  15. 使用朴素贝叶斯过滤垃圾邮件
  16. 以太坊Solidity之Truffle的使用流程与集成指南
  17. SQLServer2008 快捷键集合
  18. Php设计模式之【适配器模式 Adapter Pattern】
  19. php公众号批量推送,微信公众号文章如何批量发送给指定的用户
  20. Grad-CAM论文总结

热门文章

  1. 百度云尹世明:用ABC让复杂的营销更简单
  2. 通过竞品分析来挖掘产品卖点
  3. 图像分割:基于阈值(Otsu)
  4. 目前有哪些大公司在应用Go语言?
  5. 如何区分实用新型专利和发明专利
  6. Windows server 2012 Web服务
  7. 转载:Windows的进程创建和映像装入
  8. 小程序分享功能实现结果回调以及页面传参
  9. @Value的几种常用用法
  10. ABP入门教程(三)添加一个领域层和一个应用层