轮廓线DP

news/2024/12/27 13:56:58/文章来源:https://www.cnblogs.com/HarlemBlog/p/18548048
更新日志

概念

类似于状态压缩DP,但我们储存的是轮廓线上的状态。

有些时候,也不需要进行状态压缩,而可以用某一点的状态代表一个区域的状态。

思路

轮廓线就是已经决策的与尚未决策的部分的分界线,我们储存分界线上已经决策过的所有节点的状态。

借图OI-wiki:

pic

图中最粗的那一条就是轮廓线。储存的状态可以为第三行前两个与第二行后两个。

直接上例题。

例题

HDU1400

骨牌覆盖,经典问题。

我们考虑状态,\(0\) 表示尚未被覆盖,\(1\) 表示已经被覆盖。

我们是逐格推进的。每次更新时,都只需要枚举这一格的轮廓线状态。(当前格视作已决策的情况下)

  • 当前格子状态为 \(0\)
    那么只能不放。因此,由于要填满整个棋盘,它上面的格子必须已经被覆盖,也就是必须为 \(1\),可以用异或表示(因为二者在同一位上,且当前位为 \(0\)
    在下方代码中,\(t\) 表示当前所在格子编号,\(s\) 表示状态,\(j\) 表示横坐标。

    \[f[t][s]=f[t-1][s\oplus 1<<j] \]

  • 当前格子状态为 \(1\)
    那么可以横着放,也可以竖着放。
    • 横着放,要求前一位必须为空(至少得有前一位,不能放出界)。同时,当前状态的前一位状态也应该是 \(1\),因为横着放必然也会盖上其左侧的格子。所以也可以使用异或表示。
      同时,这个格子的上面一个格子必须已经被覆盖了,由于这一位状态本来就是 \(1\),所以可以直接使用,无需改变状态。

      \[f[t][s]=f[t][s]+f[t-1][s\oplus 1<<j-1] \]

    • 竖着放,对于前一位就没有什么要求了,但是这一位的上一个格子必须为 \(0\),同理可得异或即可。

      \[f[t][s]=f[t][s]+f[t-1][s\oplus 1<<j] \]

初始化:第一行的前一行视作全部填满,其他状况均无可能。

答案:最后一行不能留空,答案就是 \(f[t][(1<<m)-1]\)\(m\) 表示总列数。

代码
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef double db;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
template <typename Type>
using vec=vector<Type>;
template <typename Type>
using grheap=priority_queue<Type>;
template <typename Type>
using lrheap=priority_queue<Type,vector<Type>,greater<Type> >;
#define fir first
#define sec second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define dprint(x) cout<<#x<<"="<<x<<"\n"const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7/*998244353*/;const int N=11;int n,m;
ll f[2][2<<N];
ll ans;void solve(){if(n<m)swap(n,m);int i,wc;memset(f,0,sizeof(f));f[0][(1<<m)-1]=1;ans=0;for(i=0,wc=1;i<n;i++){for(int j=0;j<m;j++,wc^=1){for(int s=0;s<(1<<m);s++){if(s>>j&1){f[wc][s]=f[wc^1][s^(1<<j)];if(j>0&&(s>>j-1&1))f[wc][s]+=f[wc^1][s^(1<<j-1)];}else f[wc][s]=f[wc^1][s^(1<<j)];}}}cout<<f[wc^1][(1<<m)-1]<<"\n";
}int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);while(cin>>n>>m)solve();return 0;
}

LG1437

可以用最下侧的点状态表示其一整个倒三角的状态。

分别储存删除这个点的价值和使这个三角形为空的最大价值即可。

考虑从其右上角转移得到当前点,然后加上与它同列且在其上方的所有价值,代表删除这个点。

是这个三角形为空,可以先使它下面一个三角形为空,也可以删除当前节点,更新即可。

实时统计答案。

代码
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
typedef double db;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef pair<ll,int> pli;
template <typename Type>
using vec=vector<Type>;
template <typename Type>
using grheap=priority_queue<Type>;
template <typename Type>
using lrheap=priority_queue<Type,vector<Type>,greater<Type> >;
#define fir first
#define sec second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define dprint(x) cout<<#x<<"="<<x<<"\n"const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7/*998244353*/;const int N=55;int n,m;
int a[N][N];
ll s[N][N];
ll res[N][N][N*N];//使三角空
ll dlt[N][N][N*N];//删除这个三角
ll ans;int main(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=n-i+1;j++){cin>>a[i][j];s[i][j]=s[i-1][j]+a[i][j];}}//right->left down->upfor(int j=n;j>=1;j--){for(int i=n-j+1;i>=0;i--){for(int k=i*(i+1)/2;k<=m;k++){dlt[i][j][k]=res[max(0,i-1)][j+1][k-i]+s[i][j];res[i][j][k]=max(res[i+1][j][k],dlt[i][j][k]);ans=max(ans,res[i][j][k]);}}}cout<<ans;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834058.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nuxt.js 应用中的 schema:written 事件钩子详解

title: Nuxt.js 应用中的 schema:written 事件钩子详解 date: 2024/11/15 updated: 2024/11/15 author: cmdragon excerpt: schema:written 钩子是 Vite 提供的一种生命周期钩子,在模式写入完成后调用。通过这个钩子,开发者可以在配置被正式应用之后执行一些后续操作,比如记…

概率与期望基础

实验、结果、样本空间、事件 事件 \(A\) 是否发生取决于一系列影响它的因素,这些因素影响 \(A\) 的过程称为一次 experiment 实验 或 trial 试验 一次试验的 result 结果 称为它的 outcome 结局。\(\text{result}\) 指由原因所引起的结果 \(\text{outcome}\) 强调事件特有的结…

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明 @目录4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明前言1. Ribbon 介绍1.1 LB(Load Balance 负载均衡)2. Ribbon 原理2.2 Ribbon 机制3. Spring Cloud Ribbon 实现负载均衡算法-应用实例4. 总结:5. 最后:前…

WSL2的介绍和使用

WSL2的介绍和使用 一、什么是WSL2? WSL是Windows Subsystem for Linux的简称,它是微软为Win10和Win11引入的一项功能。WSL允许用户在Windows上运行Linux操作系统及其相关命令和应用程序,而无需使用虚拟机或安装双系统。 1.1 WSL2与WSL1、传统虚拟机比较WSL1:没有完整的Linu…

插件大总结

加注释插件搜索接口插件mybatis-plus插件

Windows系统日志报错:生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。TLS协议所定义的严重错误代码是10。Windows SChannel错误状态是1203是怎么回事?

当我们检查Windows系统日志发现有一个报错:生成了一个严重警告并将其发送到远程终结点。这会导致连接终止。TLS协议所定义的严重错误代码是10。Windows SChannel错误状态是1203。导致报错的原因是什么?该如何处理?驰网飞飞和你分享当我们检查Windows系统日志发现有一个报错:…

Windows三种提权实验

以win7为例手动提权 上线 将一句话木马上传到win7当中,本地使用蚁剑进行链接。信息收集 systeminfo查询杀软信息 wmic process list briefWindows杀软在线查询无匹配杀软进程。 根据系统信息和杀软信息查询提权EXP Windows 提权辅助 | 在线安全工具以列出的微软编号MS17-017为…

量化训练及精度调优经验分享

本文提纲:fx 和 eager 两种量化训练方式介绍 量化训练的流程介绍:以 mmdet 的 yolov3 为例 常用的精度调优 debug 工具介绍 案例分析:模型精度调优经验分享第一部分:fx 和 eager 两种量化训练方式介绍 首先介绍一下量化训练的原理。上图为单个神经元的计算,计算形式是加权…

Tomcat Windows 服务 JVM 内存参数设置

Tomcat 在 Windows 平台上启动服务的方式是 Commons Daemon,JVM 的启动参数可以有多种设置方法。本文介绍 Commons Daemon 的大致组成和参数设置方法。 Commons Daemon 由两部分组成。 一是由 C 语言开发负责和操作系统交互的平台相关程序,在 Windows 上平台相关部分是 procr…

FileZilla的安装配置和使用教程

一、FileZilla简介 FileZilla是一款免费开源的FTP软件,有以下优点:非常易于使用,且跨平台(Linux、Windows、MacOs等) 支持FTP、FTPS、SFTP等多种文件传输协议 支持断点续传 支持建立多个标签(标签为一个FTP连接界面)同时工作 支持远程查找文件 自带功能强大的站点管理和…

云行 | 金陵古都焕发数智活力,天翼云为南京创新发展注入新动能!

10月29日,以“国云智算聚金陵 自主可控铸新基”为主题的天翼云中国行江苏南京站活动圆满举办。南京市数据局领导、中国电信江苏分公司领导、客户及合作伙伴代表莅临现场,共商转型发展新机遇,共创智慧江苏新未来。会上举行了天翼云全栈自主可控能力升级计划、南京城市算力调度…

10月回顾 | Apache SeaTunnel社区动态与进展一览

各位热爱 Apache SeaTunnel 的小伙伴们,社区10月份月报来啦,请查收! 这里将记录Apache SeaTunne社区每月动态和进展,欢迎关注。 月度Merge之星 感谢以下小伙伴上个月为 Apache SeaTunnel 所做的精彩贡献(排名不分先后):@Hisoka-X,@prclin,@JohnTeslaa,@happyboy1024,@ji…