參考了乙個博主的文章,他用的是揹包問題來講解的狀壓dp,我個人感覺講的很不錯,所以就想寫一遍文章來**感受和學習總結,算是入門,因為以前一直感覺狀壓dp很難,一直理解不透,看完這篇文章確實感覺理解的更好啦。
揹包問題可能大家都不陌生,今天就用揹包講一下狀壓dp原理,首先dp就要
1.先定義狀態:
那麼考慮到n個物品,只有兩種狀態選與不選,所以二進位制數0和1足以表示狀態集,因為如果開個n為陣列的話,這樣對於空間的浪費是很嚴重的,如果n個都選就是就是 1111…n個1,都不選就是n個0,到這裡大家可以看到其實空間其實已經壓縮到乙個維度啦,這個過程就叫做狀態壓縮。
2.狀態轉移方程:
這個相信大家都可想到啦,那就是比如說dp[10000]只能是dp[00000]+w[1],諸如此類大家應該可以理解。
3.求解問題
**如下:
#include
const
int inf =
1<<15;
int dp[inf +10]
;int dp1[inf+10]
;//定義狀態
void
print1
(int num)
;//列印在狀態為num的時候的所有物品放與不放的情況
/*3 6
2 53 8
4 9 //一組樣例
0 0 0
1 5 2
01 8 3
11 13 5
001 9 4
101 14 6
011 17 7
111 22 9
*/int
main()
}}for(
int i =
0; i <(1
<< n)
; i++)}
return0;
}void
print1
(int num)
}
題目描述:
n個人在做傳遞物品的遊戲,編號為1-n。
即物品只能經過同乙個人一次,而且每次傳遞過程都有乙個代價;不同的人傳給不同的人的代價值之間沒有聯絡;
求當物品經過所有n個人後,整個過程的總代價是多少。
輸入格式:
第一行為n,表示共有n個人(16>=n>=2);
以下為n*n的矩陣,第i+1行、第j列表示物品從編號為i的人傳遞到編號為j的人所花費的代價,特別的有第i+1行、第i列為-1(因為物品不能自己傳給自己),其他資料均為正整數(<=10000)。
(對於50%的資料,n<=11)。
輸出格式:
乙個數,為最小的代價總和。
輸入樣例:
-1 9794
2724 –1
輸出樣例:
2724
演算法分析:看到2<=n<=16,應想到此題和狀態壓縮dp有關。每個人只能夠被傳遞一次,因此使用乙個n位二進位制數state來表示每個人是否已經被訪問過了。但這還不夠,因為從這樣的狀態中,並不能清楚地知道現在物品在誰 的手中,因此,需要在此基礎上再增加乙個狀態now,表示物品在誰的手上。
所以二維狀壓dp就可以解決啦。
假設dp[state][now] state代表當前n個人的狀態集,now代表目前在哪個人手中,
所以dp[state][now]=min(dp[state][now],dp[pre][t]+e[now][t])
代表從now->t的轉移方程
【**分析]
#include
#include
#include
using
namespace std;
int n,a[20]
[20],dp[
1<<16]
[20],ans=
0x3f3f3f3f
;int
main()
}memset
(dp,
0x3f3f3f3f
,sizeof
(dp));
for(
int i=
0; i)for
(int i=
0; i<
1<}}
}for
(int i=
0; i)printf
("%d"
,ans)
;}
這裡稍微涉及到的一些位運算規則大家可以參考這個大佬的文章:
位運算規則
第一章學習筆記
看c primer已經好幾遍了,但是還是有很多基礎的問題,總是那樣容易忘記,這次看的時候,決定好好的寫寫讀書筆記 希望能夠認真的堅持下去。incluede的兩種不同格式 include some file 表明檔案是乙個標準工程,查詢先檢查預定義的目錄。include my file 表明改檔案是使...
Linux學習 第一章
1.linux應用程式 可執行檔案 計算機可以直接執行的程式 的.bat cmd 檔案。2 path 變數,新增路徑,使用 分隔 3 linux 使用正斜線 分隔檔名裡的目錄名,4 標頭檔案 提供對 常量的定義和對系統函式及庫函式 呼叫的宣告 一般位於 usr include 目錄及其子目錄中 依賴...
機器學習第一章
q 什麼是機器學習 機器學習不同於以往的計算機程式設計,致力於研究如何通過計算機手段,利用以往的經驗來改善系統自身的效能。一般的程式設計都是明確的告訴電腦該做什麼。機器學習希望提供資料給學習演算法,讓它自己學習,找到其種的規律。在面對新情況的時候就能應用已產生的模型,提供相應的判斷。機器學習的本質任...