5104 I-country

在 N*M 的矩阵中,每个格子有一个权值,要求寻找一个包含 K 个格子的凸连通块(连通块中间没有空缺,并且轮廓是凸的,如书中图片所示),使这个连通块中的格子的权值和最大。求出这个最大的权值和,并给出连通块的具体方案。本题有SPJ,输出任意一种方案即可。N,M≤15,K≤225。

  • 用f[i,j,l,r,x,y]表示前i行选择了j个格子,其中第i行选择了第l到第r个格子(若不选则均为0),左边界的单调类型为X,右边界的单调类型为y(0表示递增,1表示递减)时,能构成的凸联通快的最大权值和。
  • 状态转移:借用大佬博客
  • 1.左边界列号递减,右边界列号递增(两边界都处于扩张状态)
    f[i,j,l,r,1,0] = A[i][r]-A[i][l] + max{f[i-1,j-(r-l+1),p,q,1,0]};//j>r-l+1>0
         = A[i][r]-A[i][l] + max{f[i-1,0,0,0,1,0]};//j=r-l+1>0
    2.左右边界列号都递减(左边界扩张,右边界收缩)
    f[i,j,l,r,1,1] = A[i][r]-A[i][l] + max{max{f[i-1,j-(r-l+1),p,q,1,y]}(0<=y<=1)}
    3.左右边界列号都递减(左边界收缩,右边界扩张)
    f[i,j,l,r,0,0] = A[i][r]-A[i][l] + max{{f[i-1,j-(r-l+1),p,q,x,0](0<=x<=1)}}
    4.左边界列号递增,右边界列号递减(两边界都处于收缩状态)
    f[i,j,l,r,0,1] = A[i][r]-A[i][l] + max{max{max{f[i-1,j-(r-l+1),p,q,x,y]}(0<=y<=1)}(0<=x<=1)}(p<=l<=r<=q)
    对于2,3,4的max嵌套max,可能有点难以理解
    我们来想一下,我们要进行收缩,那么我们这个收缩的状态是怎么得来的?
    答:由上一行扩张或收缩而来
    所以当收缩右边界时,我们先比较的是上一行右边界标记扩张和右边界标记收缩的最大值,再和当前行比较
    左边界收缩时同理。
    这样我们就能推出2和3。
    进而我们想4这种情况。
    左右边界同时进行收缩,我们就要嵌套3次,先由上述确定右边界状态,再由已确定右边界状态来确定左边界状态,最后由已确定的左边界状态和右边界状态来确定当前行
    //此处状态单指标记为收缩或扩张,即上一行的左/右边界由上上一行的左/右边界扩张或收缩得到

    本题还要求输出方案。
    在动态规划需要给出方案时,通常做法是额外使用一些与DP状态大小相同的数组记录下来每个状态,通过递归返回最初的状态,然后逐层退出的同时输出方案

    代码:

 #include <cstdio>
#include <cstring>
#include <cctype> template <typename T>
inline T max(T a,T b){
return a>b ? a : b;
}
template <typename T>
inline T min(T a,T b){
return a<b ? a : b;
}
template <typename T>
inline void read(T &x)
{
x=;
int p=; char ch=getchar();
while(!isdigit(ch)&&ch!='-') if(ch=='-') p=-,ch=getchar(); while(isdigit(ch)) x=(x<<)+(x<<)+(ch-''),ch=getchar();
x=p*x;
} int n,m,k;
int a[][];
int sum[][];
int i,j,l,r,x,y;
int f[][][][][][];
struct method{
int l,r,x,y;
}met[][][][][][]; inline void update(int dat,int nl,int nr,int nx,int ny)
{
int &a=f[i][j][l][r][x][y];
if(dat<=a) return ;
method &p=met[i][j][l][r][x][y];
a=dat;
p=method{nl,nr,nx,ny};
} void print(int i,int j,int l,int r,int x,int y)
{
if(j<=) return;
method &p=met[i][j][l][r][x][y];
// printf("%d\n",j);
print(i-,j-(r-l+),p.l,p.r,p.x,p.y); for(int s=l ; s<=r ; s++)
printf("%d %d\n",i,s);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(i= ; i<=n ; i++)
for(j= ; j<=m ; j++) scanf("%d",&a[i][j]),sum[i][j]=sum[i][j-]+a[i][j]; for(i= ; i<=n ; i++)
for(j= ; j<=k ; j++)
for(l= ; l<=m ; l++)
for(r=l ; r<=m ; r++)
{
int t=r-l+;
int now=sum[i][r]-sum[i][l-];
if(t>j) break;
//左减右增
x=,y=;
for(int p=l ; p<=r ; p++)
for(int q=p ; q<=r ; q++)
{
update(f[i-][j-t][p][q][][]+now,p,q,,);
}
//左减右减
x=,y=;
for(int p=l ; p<=r ; p++)
for(int q=r ; q<=m ; q++)
{
update(f[i-][j-t][p][q][][]+now,p,q,,);
update(f[i-][j-t][p][q][][]+now,p,q,,);
}
//左增右增
x=,y=;
for(int p= ; p<=l ; p++)
for(int q=l ; q<=r ; q++)
{
update(f[i-][j-t][p][q][][]+now,p,q,,);
update(f[i-][j-t][p][q][][]+now,p,q,,);
}
//左增右减
x=,y=;
for(int p= ; p<=l ; p++)
for(int q=r ; q<=m ; q++)
{
update(f[i-][j-t][p][q][][]+now,p,q,,);
update(f[i-][j-t][p][q][][]+now,p,q,,);
update(f[i-][j-t][p][q][][]+now,p,q,,);
update(f[i-][j-t][p][q][][]+now,p,q,,);
}
}
int ans=;
int ai,al,ar,ax,ay;
for(i= ; i<=n ; i++)
for(l= ; l<=m ; l++)
for(r=l ; r<=m ; r++)
for(x= ; x<= ; x++)
for(y= ; y<= ; y++)
{
if(f[i][k][l][r][x][y]>ans)
{
ans=f[i][k][l][r][x][y];
ai=i,al=l,ar=r,ax=x,ay=y;
}
}
printf("Oil : %d\n",ans);
print(ai,k,al,ar,ax,ay);
return ;
}

5104 I-country的更多相关文章

  1. wifi的country code

    转自:http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.htmlCountry A 2 A 3 Number ------------- ...

  2. hdu 5104 素数打表水题

    http://acm.hdu.edu.cn/showproblem.php?pid=5104 找元组数量,满足p1<=p2<=p3且p1+p2+p3=n且都是素数 不用素数打表都能过,数据 ...

  3. ural 1073. Square Country

    1073. Square Country Time limit: 1.0 secondMemory limit: 64 MB There live square people in a square ...

  4. 最小生成树 kruskal hdu 5723 Abandoned country

    题目链接:hdu 5723 Abandoned country 题目大意:N个点,M条边:先构成一棵最小生成树,然后这个最小生成树上求任意两点之间的路径长度和,并求期望 /************** ...

  5. 01背包 URAL 1073 Square Country

    题目传送门 /* 题意:问n最少能是几个数的平方和 01背包:j*j的土地买不买的问题 详细解释:http://www.cnblogs.com/vongang/archive/2011/10/07/2 ...

  6. 计算机学院大学生程序设计竞赛(2015’12)The Country List

    The Country List Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU 5723 Abandoned country(落后渣国)

    HDU 5723 Abandoned country(落后渣国) Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 ...

  8. hduacm 5104

    http://acm.hdu.edu.cn/show #include <cstdio> #include <cstring> #include <algorithm&g ...

  9. hdu 5104 Primes Problem

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5104 Primes Problem Description Given a number n, ple ...

  10. HDU 5723 Abandoned country (最小生成树 + dfs)

    Abandoned country 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5723 Description An abandoned coun ...

随机推荐

  1. 670. Maximum Swap 允许交换一个数 求最大值

    [抄题]: Given a non-negative integer, you could swap two digits at most once to get the maximum valued ...

  2. 项目介绍4 y有用

    在青岛做了两年开发,大大小小参与过三个项目的开发,一个是某公司内部的人员管理系统,一个是物流项目,最近做的是一个电商项目. 前两个项目采用的是ssh框架搭建的,最近的项目采用的是ssm框架搭建的.在实 ...

  3. 关于在64位win7下运行Virtualbox安装系统时出错(提示VBoxDD.DLL错误)的解决方

    安装没有问题,安装了最新版VirtualBox-4.3.18-96516-Win,一点运行想安装系统时就出错. 这是提示的错误: 运行Virtualbox去安装系统时出错:Failed to open ...

  4. 怎样在本地电脑上连接另外一台电脑上的mysql数据?(代码示例)

    基本上有两种方式: 1,使用MYSQL的管理工具,可以远程连接,比如用导航猫系列的,只要知道对方IP,然后就可以自己输入账号密码连接了. 2,使用代码连接. Java代码示例: package com ...

  5. Linux静态库与动态库详解

    引言 为了代码的复用性和模块化,我们常常使用一些库文件,在Windows操作系统下位.lib .dll作为静态库和动态库的后缀名. 在Linux下,静态链接库名字一般为libabcdef.a,其中ab ...

  6. revert

    git revert是用一次新的commit来回滚之前的commit

  7. Spring思维导图(AOP篇)

    什么是aop AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP允许 ...

  8. java网站如何集成facebook第三方登录

    第一次接触Facebook第三方登录,可能有些地方做的并不全面,只是尝试着做了一个小demo,因为国内接入Facebook的项目并不多,并且多数都是Android或iOS的实现,所以资料也特别少,在此 ...

  9. C#通过Redis实现分布式锁

    Redis有三个最基本属性来保证分布式锁的有效实现: 安全性: 互斥,在任何时候,只有一个客户端能持有锁. 活跃性A:没有死锁,即使客户端在持有锁的时候崩溃,最后也会有其他客户端能获得锁,超时机制. ...

  10. 前端福利之改变placeholder颜色的方法(转)

    之前拿到一个设计图,Placeholder是白色的,所以就查看了一下改变placeholder的方法: input::-webkit-input-placeholder { /* WebKit bro ...