博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P3227 BZOJ 3144 [HNOI2013]切糕
阅读量:6648 次
发布时间:2019-06-25

本文共 3561 字,大约阅读时间需要 11 分钟。

题目描述

经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B。出于美观考虑,小 A 希望切面能尽量光滑且和谐。于是她找到你,希望你能帮她找出最好的切割方案。

出于简便考虑,我们将切糕视作一个长 P、宽 Q、高 R 的长方体点阵。我们将位于第 z层中第 x 行、第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z)。一个合法的切面满足以下两个条件:

  1. 与每个纵轴(一共有 P*Q 个纵轴)有且仅有一个交点。即切面是一个函数 f(x,y),对于所有 1≤x≤P, 1≤y≤Q,我们需指定一个切割点 f(x,y),且 1≤f(x,y)≤R。

  2. 切面需要满足一定的光滑性要求,即相邻纵轴上的切割点不能相距太远。对于所有的 1≤x,x’≤P 和 1≤y,y’≤Q,若|x-x’|+|y-y’|=1,则|f(x,y)-f(x’,y’)| ≤D,其中 D 是给定的一个非负整数。 可能有许多切面f 满足上面的条件,小A 希望找出总的切割点上的不和谐值最小的那个。

//尽管洛谷上有了上面的文字题面,但是这副图片在别的博客上那么多见,我还是放上来吧

 

输入输出格式

输入格式:

 

第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1<=x<=P, 1<=y<=Q, 1<=z<=R)。 100%的数据满足P,Q,R<=40,0<=D<=R,且给出的所有的不和谐值不超过1000。

 

输出格式:

 

仅包含一个整数,表示在合法基础上最小的总不和谐值。

 

输入输出样例

输入样例#1:
2  2 216  16  12  62  6
输出样例#1:
6

说明

最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1

 

吐槽

  我为什么最近会突然开始刷网络流呢?因为最近在长乐一中集训,难得美国队长妹滋滋大佬来讲课,讲了一整天的网络流,我记了差不多20页信笺纸的笔记……(听课时开着电脑会损失很大的,不骗你,记笔记是个很好的学习习惯啊) 那天听得我脑力耗尽,去吃中午饭时让同行的Neil描述成——让他想到了一个游戏“饥荒”。详见……

  最近请教某些大佬时遭到了BS,RP暴涨啊,常数巨小,下面的代码占领了洛谷的rank1~3(我交了三次嘻嘻),不开O2时正好rank20(交那三次之前)。

  真记不得这个题面玩的梗是咋回事了……好像那是我初二上学期的时候,那段时间嫦娥几号来着还着陆在月球来着,我那晚看了CCTV三个小时的直播。记得那时日子多么美好…………

  好了,暂停回忆吧,咳咳!开始讲题——

解题思路

   一道离散变量模型裸题。妹滋滋的幻灯片上这么说的——//不知道这样是否违反了某些基本法,如果有请告知,我删除

  对于切糕这题——

源代码

#include
#include
#include
#include
int p,q,r,D;int cake[42][42][42]={
0};int s,t;struct Edge{ int next,to,c;}e[200010];int head[200010],cnt=2;void add(int u,int v,int c){ e[cnt]={head[u],v,c}; head[u]=cnt++; e[cnt]={head[v],u,0}; head[v]=cnt++;}int dis[200010]={
0};bool bfs(){ memset(dis,0,sizeof(dis)); dis[s]=1; std::queue
q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(e[i].c==0||dis[v]) continue; dis[v]=dis[u]+1; q.push(v); } } return dis[t]!=0;}int dfs(int u,int flow){ if(flow==0||u==t) return flow; int flow_sum=0; for(int i=head[u];i;i=e[i].next) { int v=e[i].to,f=std::min(e[i].c,flow-flow_sum); if(dis[v]!=dis[u]+1||!e[i].c) continue; int temp=dfs(v,f); e[i].c-=temp; e[i^1].c+=temp; flow_sum+=temp; if(flow<=flow_sum) break; } if(flow_sum==0) dis[u]=-1; return flow_sum;}int dinic(){ int ans=0; while(bfs()) while(int temp=dfs(s,0x7f7f7f7f)) ans+=temp; return ans;}inline int id(int x,int y,int z){ if(z==0) return s; if(z==r+1) return t; return (z-1)*p*q+(x-1)*q+y;}int main(){ //freopen("test.in","r",stdin); scanf("%d%d%d%d",&p,&q,&r,&D); s=p*q*r+1,t=s+1; for(int i=1;i<=r;i++) for(int j=1;j<=p;j++) for(int k=1;k<=q;k++) scanf("%d",&cake[j][k][i]);//网络流的题输入都很恶心,优化高维数组取值太饶了,索性不搞 ; /***建图***/ int bh[4][2]={
{
0,1},{
0,-1},{-1,0},{
1,0}}; for(int i=1;i<=p;i++) { for(int j=1;j<=q;j++) { for(int k=1;k<=r;k++) { add(id(i,j,k-1),id(i,j,k),cake[i][j][k]); if(k>D)//四周 { int h=k-D; for(int aa=0;aa<4;aa++) { int ii=i+bh[aa][0],jj=j+bh[aa][1]; if(ii>0&&ii<=p&&jj>0&&jj<=q) add(id(i,j,k),id(ii,jj,h),0x7f7f7f7f); } } } add(id(i,j,r),t,0x7f7f7f7f); } } printf("%d",dinic()); return 0;}

 

转载地址:http://ztyto.baihongyu.com/

你可能感兴趣的文章
TFRecord 的使用
查看>>
Python正则表达式指南中半部
查看>>
删除数据库所有表 序列号
查看>>
Day12 KVM构建与管理(Service01)
查看>>
【exp/imp】将US7ASCII字符集的dmp文件导入到ZHS16GBK字符集的数据库中
查看>>
强制进程产生coredump,检测死锁以及进程快照
查看>>
$.noConflict()方法--常用的方式
查看>>
PostgreSQL APP海量FEED LOG实时质量统计CASE(含percentile_disc)
查看>>
linux服务器挂载windows共享目录
查看>>
使用Putty密钥认证机制远程登录Linux
查看>>
Outlook转发所有邮件到另一个邮箱或接收人
查看>>
Python套接字对象(内建)方法
查看>>
Oracle RAC FailOver配置
查看>>
【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记4 MVC enum Tuple Dictionary
查看>>
SQL Server2008密钥
查看>>
django学习之pythonbrew部署开发环境
查看>>
ulimit open files linux打开文件数设置验证
查看>>
asp.net母板使用注意
查看>>
SQL语句的各类联接
查看>>
技术分享连载(九十六)
查看>>