zjnu1745 DOMINE (状压dp+1*2铺砖)
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
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铺砖)的更多相关文章
- 状压DP天秀
状压DP,依靠的是把状态用某种压缩方式表示出来进而DP,大多数时候是二进制状压. 直接看例题吧. 一双木棋 九尾狐吃棉花糖 islands and bridges 愤怒的小鸟 芯片 ...
- 【XSY2745】装饰地板 状压DP 特征多项式
题目大意 你有\(s_1\)种\(1\times 2\)的地砖,\(s_2\)种\(2\times 1\)的地砖. 记铺满\(m\times n\)的地板的方案数为\(f(m,n)\). 给你\(m, ...
- poj1038 Bugs Integrated,Inc. (状压dp)
题意:N*M的矩阵,矩阵中有一些坏格子,要在好格子里铺2*3或3*2的地砖,问最多能铺多少个. 我的方法好像和网上流传的方法不太一样...不管了.... 由数据范围很容易想到状压dp 我们设某个状态的 ...
- 铺地砖|状压DP练习
有一个N*M(N<=5,M<=1000)的棋盘,现在有1*2及2*1的小木块无数个,要盖满整个棋盘,有多少种方式?答案只需要mod1,000,000,007即可. //我也不知道这道题的来 ...
- dp,状压dp等 一些总结
也就作业几题而已,分析一下提醒 最重要的就是,记住,没用的状态无论怎么转移最后都会是没用的状态,所以每次转移以后的有值的状态都是有用的状态. 几种思考方向: 第一种:枚举当前的状态,转移成另外一个状态 ...
- 【BZOJ2064】分裂 状压DP
[BZOJ2064]分裂 Description 背景:和久必分,分久必和...题目描述:中国历史上上分分和和次数非常多..通读中国历史的WJMZBMR表示毫无压力.同时经常搞OI的他把这个变成了一个 ...
- poj2411 Mondriaan's Dream[简单状压dp]
$11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- [Poj2411]Mondriaan's Dream(状压dp)(插头dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18096 Accepted: 103 ...
随机推荐
- [日常填坑系列]CAP食用指南-版本引用问题
一.前言 最近,由于好久没升级底层框架,一直用着netcore2.2版本,导致有些包没能更新到最新的版本,例如:CAP. 然而,在最近升级到CAP:3.1.2版本的时候,发现有点小坑,只能退回到CAP ...
- 利用css和jquery制成弹幕
1.首先上图看下效果 2.废话不多说,直接上代码 1>html代码 <div class="barrage"> <div class="scree ...
- toad for oracle自定义快捷sql
View--->Toad Options--->Behavior--->Auto replace--->
- Java-web易混淆知识点整理
Java-web易混淆知识点 post和get区别 post: 数据不会显示在地址栏 安全 大小无限制 可以提交二进制文件 get: 数据显示在地址栏 不安全 get方式提交有大小限制(约4kb) 相 ...
- 手动添加Ini4idea,解决pycharm无法打开ini文件
1. 查看本地pycharm的版本号 help -> about 2. 进入官网:http://plugins.jetbrains.com,选中pycharm及相关版本,搜索ini,切到版本,下 ...
- 从零开始学spring源码之xml解析(一):入门
谈到spring,首先想到的肯定是ioc,DI依赖注入,aop,但是其实很多人只是知道这些是spring核心概念,甚至不知道这些代表了什么意思,,作为一个java程序员,怎么能说自己对号称改变了jav ...
- widnows2008双网卡双ip不同Ip段
机房内有不同段ip,因为线路不一样,比如普通带宽和cn2带宽,现有需求配置双网卡双ip ip1: 121.7*.*.* 255.255.255.192 121.7*.*129 ip2: 103.11 ...
- 在HDFS中将文件从源路径移动到目的路径。
import java.text.SimpleDateFormat; import java.util.Scanner; import org.apache.hadoop.fs.FSDataInput ...
- JVM调优 jdk版本 机器配置 建议jvm参数 备注
https://juejin.im/post/5b091ee35188253892389683 大型跨境电商JVM调优经历 前提:某大型跨境电商业务发展非常快,线上机器扩容也很频繁,但是对于线上机器的 ...
- 拓扑排序(topo sort)之 最大食物链计数( 洛谷P4017)
前言: 复习复习拓扑排序,自己把自己弄没了/kk 题目传送门 简化题意: 在一个DAG中,求从所有入度为0的点到所有出度为0的点路径的条数 md理解错题意把自己卡了半天,生物学的好的就可以直接理解为求 ...