信息學奧賽一本通 1593:【例 2】牧場的安排 | 洛谷 P1879 [USACO06NOV] Corn Fields G

【題目鏈接】

ybt 1593:【例 2】牧場的安排
洛谷 P1879 [USACO06NOV] Corn Fields G

【題目考點】

1. 狀壓動規

【解題思路】

集合狀態:n個元素中,選擇x個元素構成的集合,可以由一個n位二進制數表示。第i位為1表示選擇第i個元素,第i位為0表示不選擇第i個元素。
將在某格子種草稱為為該格子著色。
本題每行著色的情況可以設為一個集合狀態,稱為著色狀態。第i位為1表示選擇了這一行的第i個格子已著色,第i位為0表示第i個格子沒有著色。

sis_isi?表示第i行的土地狀態,sis_isi?第j位為1表示第i行第j個格子可以著色,為0表示不可以著色。

二進制下的數字位,從0開始,從低位到高位分別是第0位,第1位。。。
例:二進制數:110 :第0位為0, 第1位為1,第2位為1

解法1:狀壓動規 枚舉所有狀態

狀態定義
  • 階段:前i行,第i行的著色為集合狀態j
    第i+1行的集合狀態受到第i行著色狀態的影響,因此階段之一需要是第i行的著色狀態。
  • 決策:決定一行的著色
  • 策略:網格圖的著色方案
  • 策略集合:對前i行著色,且第i行著色為集合狀態j的所有著色方案
  • 統計量:方案數

狀態定義dpi,jdp_{i,j}dpi,j?:對前i行著色,且第i行著色為集合狀態j的著色方案總數。

狀態轉移方程
  • 策略集合:對前i行著色,且第i行著色為集合狀態j的所有著色方案
  • 分割策略集合:根據第i-1行的不同著色狀態來分割策略集合

在求dpi,jdp_{i,j}dpi,j?時,要枚舉第i行的所有著色狀態j,從中篩選出符要求的著色狀態。在此過程中需要枚舉第i-1行所有可能的著色狀態,設枚舉出的第i-1行的著色狀態為k。

  1. 著色的格子必須是這一行可以著色的格子的子集

    因此第i行的著色狀態j表示的已著色的格子必須是sis_isi?表示的已著色的格子的子集,即必須滿足s[i] & j == j
    第i-1行的著色狀態k表示的已著色的格子必須是si?1s_{i-1}si?1?表示的已著色的格子的子集,即必須滿足s[i-1] & k == k

  2. 每一行不可以有相鄰的兩個格子都著色。
    將k左移一位k<<1k<<1中第i位數為k中第i-1位數。k<<1的最低位為0。
    那么k<<1 & k的結果,就是將k的每一位與其右側相鄰一位進行按位與運算,(由于k<<1最低位為0,那么按位與的結果最低位為0)
    如果存在k的相鄰兩位都是1,那么結果不為0。如果不存在k的相鄰兩位都是1,那么結果為0。
    因此第i-1行只有滿足(k<<1 & k) == 0(或寫為!(k<<1 & k))的著色狀態符合要求。同理第i行只有滿足!(j << 1 & j)的著色狀態符合要求。

  3. 第i行的著色狀態j與第i-1行的著色狀態k同一列的格子不能都著色。
    也就是這兩個二進制數同一數位上不能都為1。
    如果k與j某一位都為1,那么k & j不為0,否則為0。
    因此k與j需要滿足(k & j) == 0(或寫為!(k & j)),才不存在第i行與第i-1行縱向上有相鄰的格子都著色。

對于第i行的符合要求的著色狀態j,找到一個符合要求的第i-1行的著色狀態k,對前i-1行著色且第i-1行的著色狀態為k的著色方案數為dpi?1,kdp_{i-1,k}dpi?1,k?
對i-1行所有滿足條件的著色狀態k,將dpi?1,kdp_{i-1,k}dpi?1,k?加和,即為對前i行著色且第i行著色狀態為j的著色方案數。
因此dpi,j=∑dpi?1,kdp_{i,j} = \sum dp_{i-1,k}dpi,j?=dpi?1,k?,j需要滿足j & s[i] == j,k需要滿足k & s[i-1] == k && !(k<<1 & k) && !(k & j)

對于初始狀態,本題可以枚舉第一行滿足沒有相鄰格子染色(即滿足j & s[1] == j && !(j<<1 & j))的染色狀態j,第一行染色狀態為j的方案有一種,設dp1,j=1dp_{1,j} = 1dp1,j?=1

或者假設第0行參與染色,第0行只存在染色狀態為0的一種情況,因此設dp0,0=1dp_{0,0}=1dp0,0?=1

最后對于第m行的所有符合j & s[m] == j的狀態j,求出為前m行染色,第m行著色狀態為j的方案數,并加和。即結果為∑dpm,j\sum dp_{m,j}dpm,j?,j滿足j & s[m] == j

注意,每次加和后都要對10810^8108取模。

解法2:狀壓動規 保存合法的狀態

本題每一行只會取沒有相鄰格子著色的狀態,那么可以先將這些一定沒有相鄰格子同時著色的集合狀態預處理出來,保存在state數組,state[i]表示第i個可用的集合狀態。
而后dpi,jdp_{i,j}dpi,j?表示的是對前i行著色,且第i行著色狀態為state[j]的方案數。
接下來在判斷著色狀態是否符合要求時,就不用判斷“要求相鄰格子不能同時著色”這一點了,即不用再寫j<<1 & jk<<1 & k

【題解代碼】

解法1:狀壓動規 枚舉所有狀態
  • 寫法1:設第1行的狀態作為初始狀態
#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以種草的集合狀態 1表示可以種,0表示不可以種 
long long dp[N][S], ans;//dp[i][j]:前i行著色,第i行集合狀態為j的方案數 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}for(int j = 0; j < 1<<n; ++j) if((j & s[1]) == j && !(j & j<<1))//j不是s[i]的子集 或 j有相鄰的著色格 dp[1][j] = 1;for(int i = 2; i <= m; ++i)for(int j = 0; j < 1<<n; ++j) if((j & s[i]) == j && !(j & j<<1))//j是s[i]的子集 同時 j沒有相鄰的著色格 for(int k = 0; k < 1<<n; ++k) if((k & s[i-1]) == k && !(k & k<<1) && !(k & j))//k不是s[i-1]的子集,或k有相鄰著色格,或k與j有上下相鄰的著色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M; for(int j = 0; j < 1<<n; ++j) if((j & s[m]) == j && !(j & j<<1))ans = (ans+dp[m][j])%M;cout << ans;return 0;
}
  • 寫法2:設第0行的狀態作為初始狀態
#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以種草的集合狀態 1表示可以種,0表示不可以種 
long long dp[N][S], ans;//dp[i][j]:前i行著色,第i行集合狀態為j的方案數 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}dp[0][0] = 1;for(int i = 1; i <= m; ++i)for(int j = 0; j < 1<<n; ++j) if((j & s[i]) == j && !(j & j<<1))//j是s[i]的子集 同時 j沒有相鄰的著色格 for(int k = 0; k < 1<<n; ++k) if((k & s[i-1]) == k && !(k & k<<1) && !(k & j))//k不是s[i-1]的子集,或k有相鄰著色格,或k與j有上下相鄰的著色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M; for(int j = 0; j < 1<<n; ++j) if((j & s[m]) == j && !(j & j<<1))ans = (ans+dp[m][j])%M;cout << ans;return 0;
}

解法2:狀壓動規 保存合法的狀態

#include<bits/stdc++.h>
using namespace std;
const int N = 12+5, S = (1<<12)+5, M = 1e8;
int m, n, s[N];//s[i]:第i行可以種草的集合狀態 1表示可以種,0表示不可以種 
int state[S], sn;//state[i]:第i個符合條件的集合狀態 
long long dp[N][S], ans;//dp[i][j]:前i行著色,第i行集合狀態為state[j]的方案數 
int main()
{int x;cin >> m >> n;for(int i = 1; i <= m; ++i)for(int j = 1; j <= n; ++j){cin >> x;s[i] = s[i]<<1 | x;}for(int i = 0; i < 1<<n; ++i) if((i & i<<1) == 0)state[++sn] = i;//把沒有相鄰的著色格的集合狀態加入state for(int j = 1; j <= sn; ++j) if((state[j] & s[1]) == state[j])dp[1][j] = 1;for(int i = 2; i <= m; ++i)for(int j = 1; j <= sn; ++j) if((state[j] & s[i]) == state[j])//j不是s[i]的子集 for(int k = 1; k <= sn; ++k) if((state[k] & s[i-1]) == state[k] && !(state[k] & state[j]))//k不是s[i-1]的子集,或k有相鄰著色格,或k與j有上下相鄰的著色格 dp[i][j] = (dp[i][j]+dp[i-1][k])%M;for(int j = 1; j <= sn; ++j) if((state[j] & s[m]) == state[j])ans = (ans+dp[m][j])%M;cout << ans;return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90557.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90557.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90557.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot創建項目的方式

一、Idea Spring initializr創建&#xff08;Spring 官網下載&#xff09; Spring官網只支持SpringBoot3.0以上&#xff0c;JDK17以上 二、idea Spring inst創建&#xff08;阿里云下載&#xff09; 阿里云可以支持JDK8的版本 Spring版本選擇2.7.6&#xff0c;選擇合適的依賴添…

云原生 —— K8s 容器編排系統

一、 簡介Kubernetes&#xff0c;也稱為K8s&#xff0c;是一個開源的容器編排系統&#xff0c;用于自動部署、擴展和管理容器化應用程序&#xff0c;幫助開發者更高效地跨集群管理應用。本文總結了 k8s 的基礎概念和技術架構。二、基礎概念1. 云原生&#xff08;Cloud Native…

SQLite中SQL的解析執行:Lemon與VDBE的作用解析

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 在 SQLite 的內部實現中&#xff0c;SQL 語句的解析與執行是一個精妙的過程&#xff0c;涉及詞法分析、語法分析、中間代碼生成與執行等多個環節。其中&#xff0c;Lemon 工具和 VDBE&#xff08;Virtual Database Engine…

C++學習筆記(十:類與對象基礎)

往篇內容&#xff1a; C學習筆記&#xff08;一&#xff09; 一、C編譯階段※ 二、入門案例解析 三、命名空間詳解 四、C程序結構 C學習筆記&#xff08;二&#xff09; 五、函數基礎 六、標識符 七、數據類型 補充&#xff1a;二進制相關的概念 sizeof 運算符簡介 補…

圖片查重從設計到實現(4)圖片向量化存儲-Milvus 單機版部署

Milvus 單機版部署 在 Docker 環境下安裝、應用和配置 Milvus 向量數據庫可以按照以下步驟進行&#xff0c;涵蓋從安裝到基礎應用的完整流程&#xff1a; 1. 部署前準備 服務器&#xff1a;建議測試環境配置 2 核 CPU、8GB 內存&#xff1b;處理 100 萬組向量數據&#xff0c;…

前端版本更新檢測機制

&#x1f4cc; 一、為什么需要前端版本更新檢測機制&#xff1f;在現代 Web 項目中&#xff0c;我們通常會通過 CDN 或緩存策略來加快頁面加載速度&#xff0c;但這也帶來了一個問題&#xff1a;用戶可能訪問的是舊版本的頁面或資源&#xff0c;而不會自動更新到最新版本。這在…

Python(09)正則表達式

特殊字符 1. 基本元字符 .&#xff1a;匹配除換行符以外的任意單個字符。 *&#xff1a;匹配前面的元素零次或多次。 &#xff1a;匹配前面的元素一次或多次。 ?&#xff1a;匹配前面的元素零次或一次。 2. 定量符 {n}&#xff1a;匹配前面的元素恰好 n 次。 {n,}&#xff1a;…

k8s容器放開鎖內存限制

參考&#xff1a;https://access.redhat.com/solutions/1257953 問題 nccl-test容器docker.io/library/nccl-tests:24.12中跑mpirun&#xff0c;buff設置為NCCL_BUFFSIZE503316480 提示out of memory&#xff1a; pod-1:78:91 [0] include/alloc.h:114 NCCL WARN Cuda failure …

基于Zigee的溫度數據采集系統

大家好&#xff0c;本文帶來的是單片機課設-基于Zigee的溫度數據采集系統。 一、設計內容和要求 基于Zigbee的數據采集系統 1.1設計內容 &#xff08;1&#xff09;分析對比Bluetooth、Zigbee、Lora方式組網的基本原理和性能差異&#xff0c;撰寫分析報告&#xff1b; &#xf…

ATH12K 驅動框架分析

文章目錄 Linux Wireless 驅動框架深入分析 **1. 核心框架層次結構** **1.1 cfg80211 子系統 (`net/wireless/`)** **1.2 mac80211 子系統 (`net/mac80211/`)** **2. ath12k 驅動架構分析** **2.1 核心管理文件** **2.2 數據路徑文件** **2.3 平臺接口文件** **2.4 功能模塊文件…

OSPF路由協議單區域

RIP的不足 以跳數評估的路由并非最優路徑 如果RTA選擇S0/0傳輸&#xff0c;傳輸需時會大大縮短為3sRIP協議限制網絡直徑不能超過16跳 收斂速度慢 RIP定期路由更新 – 更新計時器&#xff1a;定期路由更新的時間間隔&#xff0c;默認30秒。 – 失效計時器&#xff1a;失效計時器…

Kubernetes部署與管理Scrapy爬蟲:企業級分布式爬蟲平臺構建指南

引言&#xff1a;Kubernetes在爬蟲領域的戰略價值在大規模數據采集場景中&#xff0c;??容器化爬蟲管理??已成為企業級解決方案的核心。根據2023年爬蟲技術調查報告&#xff1a;采用Kubernetes的爬蟲系統平均資源利用率提升??65%??故障恢復時間從小時級縮短至??秒級?…

Web-Machine-N7靶機攻略

一.環境準備&#xff08;VBox&#xff0c;kali虛擬機&#xff0c;靶機&#xff09; 1.1Vbox下載地址: Downloads – Oracle VirtualBox 1.2將N7導入到這個虛擬機中 1.3將kali和Vbox都設置成橋接模式 1.4開啟靶機 若鼠標出不來可以使用組合技,CtrlAltDelete強制退出 二.信息…

用毫秒級視頻回傳打造穩定操控閉環之遠程平衡控制系統技術實踐

在工業自動化、遠程機器人、無人裝備等復雜作業場景中&#xff0c;遠程實時操控正逐步取代傳統“監控指令”模式&#xff0c;成為提升效率與保障安全的關鍵能力。尤其在高風險、高精度的應用環境中&#xff0c;操作者不僅要“能控”&#xff0c;更要“看得準、反應快”。 真正…

瑞薩電子RA-T MCU系列新成員RA2T1——電機控制專家

RA2T1系列微控制器基于64MHz ArmCortex-M23內核設計&#xff0c;專為單電機控制應用而優化。RA2T1集成PWM定時器&#xff0c;以及配備3個采樣保持電路的A/D轉換器等先進的模擬功能&#xff0c;適用于電動工具&#xff0c;風扇和家用電器等高效的低端電機控制方案。RA2T1支持1.6…

Java排序算法之<選擇排序>

目錄 1、選擇排序 1.1、介紹 1.2、穩定性 2、執行流程 3、java實現 4、優缺點 總結&#xff1a;Java 排序算法進階路線 O(n) 算法&#xff08;適合學習原理&#xff09; 冒泡排序&#xff08;最慢&#xff09;→ 選擇排序 → 插入排序&#xff08;推薦先學&#xff09; …

ESP8266 http收發數據

1.先修改基礎配置 make menuconfig 打開配置菜單 選擇component config 然后選擇 修改波特率為115200 保存退出 2.修改彩色日志打印的 在component config目錄下找到log output 選中點擊空格關掉彩色日志輸出&#xff0c;這樣正常串口打印就沒有亂碼了 然后保存退出 3…

ZLMediaKit 源代碼入門

ZLMediaKit 是一個基于 C11 開發的高性能流媒體服務器框架&#xff0c;支持 RTSP、RTMP、HLS、HTTP-FLV 等協議。以下是源代碼入門的詳細指南&#xff1a; 1. 源碼結構概覽 主要目錄結構&#xff1a; text ZLMediaKit/ ├── cmake/ # CMake 構建配置 ├── …

智能Agent場景實戰指南 Day 21:Agent自主學習與改進機制

【智能Agent場景實戰指南 Day 21】Agent自主學習與改進機制 文章內容 開篇 歡迎來到"智能Agent場景實戰指南"系列的第21天&#xff01;今天我們將深入探討智能Agent的自主學習與改進機制——這是使Agent能夠持續提升性能、適應動態環境的核心能力。在真實業務場景…

微信小程序中英文切換miniprogram-i18n-plus

原生微信小程序使用 miniprogram-i18n-plus第一步&#xff1a;npm install miniprogram-i18n-plus -S安裝完成后&#xff0c;會在項目文件文件夾 node_modules文件里生成 miniprogram-i18n-plus&#xff0c; 然后在工具欄-工具-構建npm&#xff0c;然后看到miniprogram_npm里面…