Description

Mirko has a chessboard with N rows and just three columns. Slavica has written an integer on each field. Mirko has K dominoes at his disposal, their dimensions being 2x1, and has to arrange all of them on the board without overlapping, in a way that each
domino covers exactly two fields of the board. He can rotate the dominoes as he pleases. 

Help Mirko cover the largest sum of numbers possible with the dominoes!

Input

The first line of input contains the integer N (1 ≤ N ≤ 1000), the number of rows, and K (1 ≤ K ≤ 1000), the number of dominoes available. Each of the following N lines contains three integers written in the ith row of the board. All numbers will be lesser
than 10^6 by absolute value

Output

The first and only line of output must contain the maximal sum possible to cover with exactly K dominoes.

Sample Input


5 3
2 1 -1
1 3 2
0 2 3
2 1 1
3 3 0

Sample Output


16

题意:给你一个n*3的矩阵,每一个格子都有对应的价值,让你在里面恰好铺满k块1*2的砖,可以竖着铺,也可以横着铺,问铺完k块砖后所能覆盖到的最大价值是多少。

思路:与poj2411全部铺满不同,这题可以不铺满,所以我们可以考虑每一层状态里0代表空缺没有铺,1代表这个格子铺过了,那么对于每一层,我们可以枚举这一层铺的状态,如果这一层有格子是竖着放的,那么我们要看看上一层的当前这个位置是不是0,如果是0就可以竖着放,我们枚举每一层的状态的时候,只考虑铺在当前这一行的格子以及可能占用上一层的砖,不考虑延伸到下一层的砖。这样我们就可以设dp[i][j][state]表示当前为i行,已经铺了k个砖,当前行的状态为state的能覆盖到的最大价值。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ldb;
#define inf 1100000000
#define pi acos(-1.0)
#define maxn 1005
int dp[2][maxn][10]; //滚动数组,dp[i][j]表示前i行,选了j个,当前行状态为state的最大总价值
int sczt[20]={0,7,6,4,5,4,1,0,3,2,0,1,0}; //这里是上一层的状态
int jia[20]= {0,3,2,2,2,1,2,1,2,1,1,1,0}; //这里是用这个状态铺砖时,增加了多少砖块
int zt[20]= {0,7,6,7,5,4,7,6,3,2,3,1,0}; //这里是当前行的状态
int a[maxn][maxn];
int getsum(int h,int idx) //这里算的是增加多少价值
{
int i,j;
if(idx==1)return a[h][1]+a[h][2]+a[h][3]+a[h-1][1]+a[h-1][2]+a[h-1][3];
if(idx==2)return a[h][1]+a[h][2]+a[h-1][1]+a[h-1][2];
if(idx==3)return a[h][1]+a[h][2]+a[h][3]+a[h-1][1];
if(idx==4)return a[h][1]+a[h][3]+a[h-1][1]+a[h-1][3];
if(idx==5)return a[h][1]+a[h-1][1];
if(idx==6)return a[h][1]+a[h][2]+a[h][3]+a[h-1][3];
if(idx==7)return a[h][1]+a[h][2];
if(idx==8)return a[h][2]+a[h][3]+a[h-1][2]+a[h-1][3];
if(idx==9)return a[h][2]+a[h-1][2];
if(idx==10)return a[h][2]+a[h][3];
if(idx==11)return a[h][3]+a[h-1][3];
if(idx==12)return 0; } int main()
{
int n,k,i,j,len,val,state,t;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=1;i<=n;i++){
for(j=1;j<=3;j++){
scanf("%d",&a[i][j]);
}
}
for(j=1;j<=k;j++){
for(state=0;state<8;state++){
dp[1][j][state]=-inf;
}
} dp[1][0][0]=0;
dp[1][1][6]=a[1][1]+a[1][2];
dp[1][1][3]=a[1][2]+a[1][3]; int tot=1;
for(i=2;i<=n;i++){
for(j=0;j<=k;j++){
for(state=0;state<8;state++){
dp[1^tot][j][state]=-inf;
}
} for(j=0;j<=k;j++){
for(t=1;t<=12;t++){ //这里枚举的是12种这一行与上一行可能的状态,即第一个格子里竖着放,第一个格子横着放,第一个格子不放等状态
for(state=0;state<8;state++){ //枚举上层状态
if((sczt[t]&state)==0 ){
if(j+jia[t]<=k){
dp[1^tot][jia[t]+j ][zt[t] ]=max(dp[1^tot][jia[t]+j ][zt[t] ],dp[tot][j][state]+getsum(i,t) );
}
}
}
}
}
tot=1^tot;
}
int maxx=dp[tot][k][0];
for(state=1;state<8;state++){
maxx=max(maxx,dp[tot][k][state] );
}
printf("%d\n",maxx);
}
return 0;
}

zjnu1745 DOMINE (状压dp+1*2铺砖)的更多相关文章

  1. 状压DP天秀

    状压DP,依靠的是把状态用某种压缩方式表示出来进而DP,大多数时候是二进制状压. 直接看例题吧. 一双木棋     九尾狐吃棉花糖     islands and bridges 愤怒的小鸟   芯片 ...

  2. 【XSY2745】装饰地板 状压DP 特征多项式

    题目大意 你有\(s_1\)种\(1\times 2\)的地砖,\(s_2\)种\(2\times 1\)的地砖. 记铺满\(m\times n\)的地板的方案数为\(f(m,n)\). 给你\(m, ...

  3. poj1038 Bugs Integrated,Inc. (状压dp)

    题意:N*M的矩阵,矩阵中有一些坏格子,要在好格子里铺2*3或3*2的地砖,问最多能铺多少个. 我的方法好像和网上流传的方法不太一样...不管了.... 由数据范围很容易想到状压dp 我们设某个状态的 ...

  4. 铺地砖|状压DP练习

    有一个N*M(N<=5,M<=1000)的棋盘,现在有1*2及2*1的小木块无数个,要盖满整个棋盘,有多少种方式?答案只需要mod1,000,000,007即可. //我也不知道这道题的来 ...

  5. dp,状压dp等 一些总结

    也就作业几题而已,分析一下提醒 最重要的就是,记住,没用的状态无论怎么转移最后都会是没用的状态,所以每次转移以后的有值的状态都是有用的状态. 几种思考方向: 第一种:枚举当前的状态,转移成另外一个状态 ...

  6. 【BZOJ2064】分裂 状压DP

    [BZOJ2064]分裂 Description 背景:和久必分,分久必和...题目描述:中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力.同时经常搞OI的他把这个变成了一个 ...

  7. poj2411 Mondriaan's Dream[简单状压dp]

    $11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...

  8. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

  9. [Poj2411]Mondriaan's Dream(状压dp)(插头dp)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18096   Accepted: 103 ...

随机推荐

  1. Laya Ts 简易对象池

    ts版本的简易对象池 ,目前主要支持3D的物体,也可以将其改成其他类型 要使用首先调用InitPool 方法 `/* 使用说明: 使用必须先调用 InitPool 方法将对象池初始化 然后 Deque ...

  2. 【JDBC核心】数据库连接池

    数据库连接池 传统模式 使用数据库的传统模式: 在主程序(servlet.beans等)中建立数据库连接: 进行 SQL 操作: 断开数据库连接. 这种模式存在的问题: JDBC 连接数据库的方式(四 ...

  3. 【C++】《Effective C++》第五章

    第五章 实现 条款26:尽可能延后变量定义式的出现时间 只要定义了一个变量而其类型带有一个构造函数或析构函数,那么 当程序的控制流到达这个变量定义式时,你得承受这个构造成本. 当这个变量离开这个作用域 ...

  4. C中的dll 、lib和exe文件

    参考:链接1   链接2 DLL 动态链接库(Dynamic Link Library,缩写为DLL),运行时加载是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源.动态链接 ...

  5. explain select * from xuehao;

    mysql> explain select * from xuehao;+----+-------------+--------+------+---------------+------+-- ...

  6. 【ORA】 ORA-01031:权限不足的问题

    今天创建一个用户,赋予dba权限,在plsql中选择sysdba登录,但是报错 ORA-01031 在网上找了好久最后的解决办法是 不仅仅要有dba权限 还要有这个权限: grant all priv ...

  7. [WPF] 在单元测试中使用 Prism 的 EventAggregator,订阅到 ThreadOption.UIThread 会报错

    1. 问题 [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { ContainerLocator ...

  8. 前端开发好帮手,eslint配置全知道

    eslint让人又爱又恨,原因在于它的默认配置非常严格,动则一个小提示就直接报错不给运行.而在开发调试的过程中,我们想时时得到运行效果,它的严格又很烦. 在安装eslint后,我们可以在package ...

  9. 2V转5V输出,2.4V转5V输出,DC-DC同步整流升压电路

    PW5100可以适用于2V转5V和2.4V转5V的应用电路中,PW5100是一颗DC-DC的同步升压转换器芯片. PW5100特点: 1, 低输入,宽范围:0.7V-5V 2, 输出电压固定,外围少: ...

  10. [CPP] STL 简介

    STL 即标准模板库(Standard Template Library),是 C++ 标准库的一部分,里面包含了一些模板化的通用的数据结构和算法.STL 基于模版的实现,因此能够支持自定义的数据结构 ...