先考虑第一个问题,即求最小的巧克力块数

将这张网格图建图(仅对$c_{i,j}\ne -1$的位置建点),即求点数最少的连通块(的点数)使得存在$k$个不同的$c_{i,j}$

(以下$c$仅用一维数组表示,$c_{i}$即表示编号为$i$的点的原来的$c_{i,j}$)

令$f_{i,S}$表示包含$i$且集合$S$中的$c_{i}$都在连通块中出现(仅要求出现,不要求其余点不出现)的点数最少的连通块(的点数),显然只需要求出这个dp数组即可,下面考虑如何求:

初始令$f_{i,0}=f_{i,\{c_{i}\}}=1$且$f_{i,j}=\infty$(其中$j>0$),之后不断利用以下几个递推式进行转移——
$$
S'\ne \empty且S'\subset S,f_{i,S}=\min(f_{i,S},f_{i,S'}+f_{i,S\setminus S'}-1)\\(i,j)\in E,f_{i,S}=\min(f_{i,S},f_{j,S}+1)
$$
换言之,只需要不断将其以此法进行修改直至无法修改即得到了正确的$f_{i,j}$,此做法正确性显然

虽然整体没转移有后效性,但第一个转移在$S$这一维上一定是从$S_{sub}$转移到$S$(其中$S_{sub}\subset S$),换言之若从小到大枚举$S$那么就可以从小到大枚举$S$,并求出对应的$f_{i,S}$(最终的值),那么一定是从前面转移

再用枚举子集的技巧优化,可以做到总计$o(n3^{C})$的复杂度(其中$C=\max c_{i}$)

更进一步的,第3个转移是一个最短路的形式(直接从dijkstra的角度来说,即对于最小的$f_{i,S}$具有后效性),当求完后再求一次类似最短路的过程即可

这里转移的复杂度是$o(n\log n\ 2^{C})$,在$C$较小时可以通过

(上面所述的也就是所谓的“斯坦纳树”,反正就是一个此类状压dp的计算方式)

当$C$较大时,上面的做法显然不行,但如果将这些$c_{i}$随机映射到$[1,k]$上(即令$C=k$),得到的解显然也是合法的(但并不一定最小)

考虑点数最小的答案是其中的某$k$个,那么只需要这$k$个中任意两个不映射到同一个位置上即可,这样的概率即为$\frac{k!}{k^{k}}$,若取$k=5$大约为0.0384

以此法做大约200次,求最小值即可得到一个较为准确的答案

另外还有需要最小化中位数,可以二分中位数$mid$,并将所有数分为0和1(小于等于$mid$或大于$mid$),在上面的状态基础上再定义一个$g_{i,S}$表示在$f_{i,S}$最小的基础上最少的1的个数即可

总复杂度为$o(TC\log A(n\log n\ 2^{k}+n3^{k}))$(其中$C=200$即操作次数,$A=\max a_{i,j}$),略卡常数

(另外测评时注意跳过样例,否则会Judgment Failed)

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 250
4 #define oo 0x3f3f3f3f
5 #define pii pair<int,int>
6 #define mp make_pair
7 #define fi first
8 #define se second
9 struct Edge{
10 int nex,to;
11 }edge[N<<2];
12 priority_queue<pair<pii,int> >q;
13 int V,E,t,n,m,k,id[N][N],c[N][N],val[N],vis[N],head[N],a[N];
14 pii ans,b[N],f[N][32];
15 pii add(pii x,pii y){
16 return mp(x.fi+y.fi,x.se+y.se);
17 }
18 pii neg(pii x){
19 return mp(-x.fi,-x.se);
20 }
21 void add(int x,int y){
22 edge[E].nex=head[x];
23 edge[E].to=y;
24 head[x]=E++;
25 }
26 void dijkstra(int S){
27 memset(vis,0,sizeof(vis));
28 for(int i=1;i<=V;i++)q.push(mp(neg(f[i][S]),i));
29 while (!q.empty()){
30 int k=q.top().second;
31 q.pop();
32 if (vis[k])continue;
33 vis[k]=1;
34 for(int i=head[k];i!=-1;i=edge[i].nex)
35 if (f[edge[i].to][S]>add(f[k][S],b[edge[i].to])){
36 f[edge[i].to][S]=add(f[k][S],b[edge[i].to]);
37 q.push(mp(neg(f[edge[i].to][S]),edge[i].to));
38 }
39 }
40 }
41 pii calc(int mid){
42 for(int i=1;i<=V;i++)
43 if (val[i]<=mid)b[i]=mp(1,0);
44 else b[i]=mp(1,1);
45 for(int i=1;i<=V;i++){
46 for(int j=1;j<(1<<k);j++)f[i][j]=mp(oo,0);
47 f[i][0]=f[i][(1<<a[i])]=b[i];
48 }
49 for(int i=1;i<(1<<k);i++){
50 for(int j=1;j<=V;j++)
51 for(int s=(i&(i-1));s;s=(i&(s-1)))f[j][i]=min(f[j][i],add(add(f[j][s],f[j][i^s]),neg(b[j])));
52 dijkstra(i);
53 }
54 pii ans=mp(oo,0);
55 for(int i=1;i<=V;i++)ans=min(ans,f[i][(1<<k)-1]);
56 return ans;
57 }
58 pii calc(){
59 int l=0,r=1e6,ans=calc(0).fi;
60 while (l<r){
61 int mid=(l+r>>1);
62 if (calc(mid).se<=ans/2)r=mid;
63 else l=mid+1;
64 }
65 return mp(ans,l);
66 }
67 int main(){
68 srand(time(0));
69 scanf("%d",&t);
70 while (t--){
71 scanf("%d%d%d",&n,&m,&k);
72 for(int i=1;i<=n;i++)
73 for(int j=1;j<=m;j++)scanf("%d",&c[i][j]);
74 V=E=0;
75 memset(head,-1,sizeof(head));
76 memset(id,0,sizeof(id));
77 for(int i=1;i<=n;i++)
78 for(int j=1;j<=m;j++){
79 if (c[i][j]>0){
80 id[i][j]=++V;
81 scanf("%d",&val[V]);
82 if ((i>1)&&(id[i-1][j])){
83 add(id[i-1][j],id[i][j]);
84 add(id[i][j],id[i-1][j]);
85 }
86 if ((j>1)&&(id[i][j-1])){
87 add(id[i][j-1],id[i][j]);
88 add(id[i][j],id[i][j-1]);
89 }
90 }
91 else scanf("%*d");
92 }
93 ans=mp(oo,0);
94 for(int times=0;times<200;times++){
95 memset(vis,-1,sizeof(vis));
96 for(int i=1;i<=n;i++)
97 for(int j=1;j<=m;j++)
98 if (c[i][j]>0){
99 if (vis[c[i][j]]<0)vis[c[i][j]]=rand()%k;
100 a[id[i][j]]=vis[c[i][j]];
101 }
102 ans=min(ans,calc());
103 }
104 if (ans.fi==oo)printf("-1 -1\n");
105 else printf("%d %d\n",ans.fi,ans.se);
106 }
107 }

[loj2977]巧克力的更多相关文章

  1. loj2977 巧克力 (斯坦纳树+随机化)

    考虑颜色比较少的时候,第一问可以直接斯坦纳树 第二问考虑二分,每次把每格的权值给成1000+[a[i]>m],就是在个数最少的基础上尽量选小于等于m的 然而颜色太多不能直接做,但可以把每种颜色映 ...

  2. 【THUSC2017】【LOJ2977】巧克力 斯坦纳树

    题目大意 有一个网格(或者你可以认为这是一个图),每个点都有颜色 \(c_i\) 和点权 \(a_i\). 求最小的连通块,满足这个连通块内点的颜色数量 \(\geq k\).在满足点数最少的前提下, ...

  3. Bzoj2850 巧克力王国

    Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 505  Solved: 204 Description 巧克力王国里的巧克力都是由牛奶和可可做成的.但 ...

  4. C Golden gun的巧克力

    Time Limit:1000MS  Memory Limit:65535K 题型: 编程题   语言: 无限制 描述 众所周知,13级有尊大神Golden gun,人称根叔,简称金枪!众立志进校队的 ...

  5. 分巧克力【来源:CSDN线上编程挑战赛】——递归,费波那奇数列,迭代

    /*====================================================================== 儿童节快到了,班长想要给班上的每个同学给一个巧克力, ...

  6. Luogu P2183 巧克力

    题目描述 佳佳邀请了M个同学到家里玩.为了招待客人,她需要将巧克力分给她的好朋友们.她有N(1<=N<=5000)块巧克力,但是大小各不一样,第i块巧克力大小为为1*Xi(1<=i& ...

  7. BZOJ2820 - 巧克力王国

    原题链接 Description 给出个二维平面上的点,第个点为,权值为.接下来次询问,给出,求所有满足的点的权值和. Solution 对于这个点建一棵k-d树,子树维护一个子树和. 如果子树所代表 ...

  8. [FWT] UOJ #310. 【UNR #2】黎明前的巧克力

    [uoj#310][UNR #2]黎明前的巧克力 FWT - GXZlegend - 博客园 f[i][xor],考虑优化暴力,暴力就是FWT xor一个多项式 整体处理 (以下FWT代表第一步) F ...

  9. 巧克力分配问题——C语言

    某品牌巧克力使用500克原料可制作55小块巧克力,请编程实现:输入原料重量(以千克为单位),计算出制作巧克力的块数(四舍五入).然后对这些巧克力进行分包,小盒放11块,大盒放24块,问各分装多少大盒多 ...

随机推荐

  1. After Effects 图层属性及属性组结构详解

    根据结构类型的属性分类 在 After Effects 的脚本开发中,图层的属性可被区分为三种类型:PROPERTY.INDEXED_GROUP 和 NAMED_GROUP .通过使用app.proj ...

  2. Linux查找运行程序主目录

    1.查看程序所在PID netstat -lntup 2.根据PID查找程序所在目录 ll /proc/PID/exe 3.查找程序配置路径 /proc/PID/exe -t

  3. Appium iOS 原理

    一.iOS Appium 原理 1.1 iOS 9.3 系统之前自动化测试 1.1.1 Native 自动化 这是 iOS 9.3 系统之前自动化测试的架构模式.通过 Android Appium 原 ...

  4. 一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白?

    一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白? 以下从死锁检测.死锁避免.死锁解决3个方面来探讨如何对MySQL死锁问题进行性能调优. 死锁检测 通过SQL语句查询锁表相关信息: ( ...

  5. 【Docker】(10)---详细说说 Dockerfile文件

    一.基础概念 1.基本概念 Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建.有了 Dockerfile,当我们需要定制 ...

  6. Solon 框架如何方便获取每个请求的响应时间?

    经常会有同学问 Solon 怎样才能获取每个请求的响应时间?要求是不需要给每个函数加注解.故此,整理了一下. 不给每个函数加注解,主要有两种方式可以获取请求响应时间: 方式1:基于全局过滤器 Solo ...

  7. 1.2 Simple Code!(翻译)

    Simple Code! 简洁编码 Playing football is very simple, but playing simple football is the hardest thing ...

  8. JVM:GC Roots

    JVM:GC Roots 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 JVM 垃圾回收的时候如何确定垃圾 什么是垃圾 简单来说就是内存中已经不再被使用的空间就 ...

  9. BUAA软件工程个人博客作业

    软件工程个人博客作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业 我在这个课程的目标 团队完成好的软件,并对自己作出规划 这个作 ...

  10. Noip模拟76 2021.10.14

    T1 洛希极限 上来一道大数据结构或者单调队列优化$dp$ 真就没分析出来正解复杂度 正解复杂度$O(q+nm)$,但是据说我的复杂度是假的 考虑一个点转移最优情况是从它上面的一个反$L$形转移过来 ...