【BZOJ】2310: ParkII 插头DP
【题意】给定m*n的整数矩阵,求经过所有点至多一次路径的最大数值和。n<=8,m<=100。
【算法】插头DP
【题解】最小表示法确实十分通用,处理简单路径问题只需要状态多加一位表示独立插头的数量0~2(即路径端点),转移的时候多考虑凭空产生独立插头和结尾为独立插头的情况即可。
可以跳格的情况直接转移就行。求最值路径和求路径数的区别就是把加改成乘。这样每行至多5种联通编号,用8进制即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=,MOD=,S=;
int n,m,map[][maxn],c[maxn],num;
struct h{
int first[MOD],nxt[S],state[S],tot;//
ll ans[S];
void init(){
memset(first,,sizeof(first));
tot=;
}
void insert(int x,ll num){
for(int i=first[x%MOD];i;i=nxt[i]){
if(state[i]==x){
ans[i]=max(ans[i],num);
return;
}
}
state[++tot]=x;ans[tot]=num;
nxt[tot]=first[x%MOD];first[x%MOD]=tot;
}
}f[];
void decode(int x){num=x&;x>>=;for(int i=m;i>=;i--)c[i]=x&,x>>=;}
int vis[];//
int encode(){
for(int i=;i<=;i++)vis[i]=;
int cnt=,x=;
for(int i=;i<=m;i++){
if(!c[i]){x<<=;continue;}
if(!vis[c[i]])vis[c[i]]=++cnt;
x=(x<<)|vis[c[i]];
}
return x=(x<<)|num;
}
bool o(int x,int y){return x<=n&&y<=m;}
void solve(int cur,int x,int y){
for(int k=;k<=f[cur^].tot;k++){
decode(f[cur^].state[k]);
int left=c[y-],up=c[y];ll ans=f[cur^].ans[k]+map[x][y];
if(left&&up){
if(left!=up){
c[y-]=c[y]=;
for(int i=;i<=m;i++)if(c[i]==left)c[i]=up;
f[cur].insert(encode(),ans);
}
}
else if(left||up){
int now=left^up;
if(o(x+,y)){
c[y-]=now;c[y]=;
f[cur].insert(encode(),ans);
}
if(o(x,y+)){
c[y-]=;c[y]=now;
f[cur].insert(encode(),ans);
}
if(num<){
num++;c[y-]=c[y]=;
f[cur].insert(encode(),ans);
}
}
else{
f[cur].insert(encode(),f[cur^].ans[k]);
if(o(x+,y)&&o(x,y+)){
c[y-]=c[y]=;
f[cur].insert(encode(),ans);
}
if(num<){
num++;
if(o(x+,y)){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
if(o(x,y+)){
c[y-]=;c[y]=;
f[cur].insert(encode(),ans);
}
}
}
}
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)scanf("%d",&map[i][j]);
int cur=;f[].init();f[].insert(,);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
f[cur^=].init();solve(cur,i,j);
}
for(int j=;j<=f[cur].tot;j++){
int num=f[cur].state[j]&;
f[cur].state[j]=((f[cur].state[j]>>)<<)|num;//
}
}
ll ANS=-1ll<<;
for(int i=;i<=f[cur].tot;i++){
if((f[cur].state[i]&)==)ANS=max(ANS,f[cur].ans[i]);
}
printf("%lld",ANS);
return ;
}
注意桶数组vis开成int类型,奇怪的问题一定是数组空间的问题。
【BZOJ】2310: ParkII 插头DP的更多相关文章
- 【BZOJ2310】ParkII 插头DP
[BZOJ2310]ParkII Description Hnoi2007-Day1有一道题目 Park:给你一个 m * n 的矩阵,每个矩阵内有个权值V(i,j) (可能为负数),要求找一条回路, ...
- [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)
转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...
- BZOJ.1210.[HNOI2004]邮递员(插头DP Hash 高精)
BZOJ 洛谷 http://www.cnblogs.com/LadyLex/p/7326874.html 插头DP.\(m+1\)个插头的状态需要用三进制表示:\(0\)表示无插头,\(1\)表示是 ...
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
1187: [HNOI2007]神奇游乐园 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 668 Solved: 337[Submit][Statu ...
- bzoj 2331: [SCOI2011]地板 插头DP
2331: [SCOI2011]地板 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 541 Solved: 239[Submit][Status] D ...
- bzoj 1210 [HNOI2004] 邮递员 插头dp
插头dp板子题?? 搞了我一晚上,还tm全是抄的标程.. 还有高精,哈希混入,还是我比较弱,orz各种dalao 有不明白的可以去看原论文.. #include<cstdio> #incl ...
- bzoj 1814 Ural 1519 Formula 1 ——插头DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...
- 【BZOJ】2331: [SCOI2011]地板 插头DP
[题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...
- 【题解】互不侵犯 SCOI 2005 BZOJ 1087 插头dp
以前没学插头dp的时候觉得这题贼难,根本不会做,学了才发现原来是一裸题. 用二进制表示以前的格子的状态,0表示没放国王,1表示放了国王. 假设当前位置为(x,y),需要记录的是(x-1,y-1)至(x ...
随机推荐
- PAT 1147 Heaps
https://pintia.cn/problem-sets/994805342720868352/problems/994805342821531648 In computer science, a ...
- sql server数据库中raiserror函数的用法
server数据库中raiserror的作用就和asp.NET中的throw new Exception一样,用于抛出一个异常或错误.这个错误可以被程序捕捉到. raiserror的常用格式如下:ra ...
- 将博客搬至CSDN和和自己的网站
将博客同步一份到CSDN去, CSDN博客地址:https://blog.csdn.net/klkfl ---------------- 分割线 2018-10-7 自己用typecho 搭建了一个博 ...
- ZOJ3733_Skycity
这...水题.可惜坑了无数发. 显然对于当前的半径的园,多边形的边数越多,周长越短,面积也就越小. 一开始我是用二分去做的,事实证明也是可以的,只是我坑了. 其实没必要去用二分哦,这样来考虑这问题. ...
- 【刷题】BZOJ 3524 [Poi2014]Couriers
Description 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0 ...
- [UVALive 3902] Network
图片加载可能有点慢,请跳过题面先看题解,谢谢 一道简单的贪心题,而且根节点已经给你了(\(S\)),这就很好做了. 显然,深度小于等于 \(k\) 的都不用管了(\(S\) 深度为0),那么我们只需要 ...
- HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举)
HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举) 题意分析 求在[1,n-1]中,m个整数的倍数共有多少个 与 UVA.10325 ...
- 安装elasticsearch5.4.1集群和head插件
这里用的系统版本是CentOS6.6. 192.168.3.56 ES01 192.168.3.49 ES02 192.168.3.57 ES03 1.为三个节点安装java环境 # yum inst ...
- 解题:USACO12FEB Nearby Cows
题面 比较简单的树形dp(递推?) 设$dp[i][j]$表示距离$i$距离为$j$的点的数目,先预处理$g[i][j]$表示点$i$的子树中距离这个点距离为$j$的点的数目(猫老师讲过,用一个栈维护 ...
- 解题:洛谷2257 YY的GCD
题面 初见莫比乌斯反演 有一个套路是关于GCD的反演经常设$f(d)=\sum_{gcd(i,j)==d},g(d)=\sum_{d|gcd(i,j)}$,然后推推推 $\sum\limits_{i= ...