Partitioning the Farm bzoj-3061 Usaco13Feb

题目大意:给定一个n*n的方格图,用k条贯穿方格图的直线将整个方格图分割,使得每一块的权值和的最大值最小。

注释:$1\le n \le 15$,$1\le k \le 2n-2$。

想法:想到dp不难,但是我想了很久怎么dp。这里介绍一个常用的小手法:横向状压,竖着正常dp。想到这里,几乎就切了。横向二进制枚举,然后dp即可。

最后,附上丑陋的代码... ...

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=20;
int a[N][N],b[N][N],c[N][N];
bool ne[N];
int n,m,t;
bool check(int k,int v)
{
int top=1,o;memset(c,0,sizeof c);
for(int i=1;i<=n;i++)
{
if(i>1&&((k>>(i-2))&1))top++;
for(int j=1;j<=n;j++)c[top][j]+=b[i][j];
}
if(top>m+1)
return 0;
o=m-top+1;
for(int l=0,r=1;r<=n;r++)
{
for(int i=1;i<=top;i++)
{
if(c[i][r]-c[i][r-1]>v)
return 0;
else
{
if(c[i][r]-c[i][l]>v)
l=r-1,o--;
}
}
}
if(o<0)return 0;return 1;
}
int main()
{
int l=0,r=0,mid,ans;bool ok;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)scanf("%d",&a[i][j]),r+=a[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)b[i][j]=b[i][j-1]+a[i][j];
}
t=(1<<(n-1));
while(r>=l)
{
mid=(l+r)>>1;ok=0;
for(int i=0;i<t;i++)
{
if(check(i,mid))
{
ok=1;
break;
}
}
if(ok)
ans=mid,r=mid-1;
else
l=mid+1;
}
printf("%d\n",ans);
}

小结:无论是二进制枚举还是直接dp,都是普及难度,但是和到一起而且不是暴力的承接关系(Superbia_zyb),还是值得称赞的。

最新文章

  1. 在春意盎然的季节里初识GIT
  2. Linux下Steam中支持中文的办法
  3. C语言 第二章 数据类型、变量和输入函数
  4. Linux服务器jps报process information unavailable
  5. windbg
  6. MYSQL中约束及修改数据表
  7. BZOJ1968 [Ahoi2005]COMMON 约数研究
  8. (笔记)angular 的hover事件
  9. POJ -- 3140
  10. 【python】初识python的问题
  11. 转:lr_eval_string函数的用法解析
  12. Kubernetes集群部署史上最详细(二)Prometheus监控Kubernetes集群
  13. 细说shiro之五:在spring框架中集成shiro
  14. repository和repertory
  15. mybatis DATE_FORMAT 格式化时间输出
  16. verilog语法实例学习(11)
  17. [原][粒子特效][spark]插值器interpolator
  18. ios Develop mark
  19. Windows 上 Nginx 路径的陷阱
  20. .net 分布式学习计划

热门文章

  1. ubuntu下如何查看和设置分辨率 (转载)
  2. 数据库得到too many connections”错误信息
  3. j建立一个小的servlet小程序
  4. drawable的文件名大写
  5. android 中的Context(一)
  6. 313 Super Ugly Number 超级丑数
  7. Scala-基础-变量与常量
  8. JavaScript入门笔记
  9. css3通过scale()实现放大功能、通过rotate()实现旋转功能
  10. 这辈子写过的比较有意思的几个sql