hdu2167之狀態壓縮

2021-08-04 20:20:02 字數 2481 閱讀 2224

題目大意:給你乙個矩陣,讓你在矩陣中找一些元素使它們加起來和最大,但是當你使用某乙個元素時,那麼這個元素周圍的其它八個元素都不能取!

需要記錄上一行的狀態數量,每一種的狀態,和從第一行到上一行每個狀態的總的元素和。

當前行的話通過dfs,求出當前行狀態的個數以及每個狀態下當前行的值。

之和比較上一行和當前行的狀態對總得元素和進行更新。

這題需要注意的是這個輸入的格式,因為每兩個案例之間是有空行的,所有讀取到'\0'即可

未優化版:

#include #include #include #include #include #include #include #include #include #include #include #define inf 99999999

typedef long long ll;

using namespace std;

const int max=1597+10;

int n,nowsize,lastsize;

int now[max],last[max];

int dp[max],temp[max],ans[max];

int w[16][16];

char s[max];

void dfs(int id,int k,int p,int sum)

dfs(id,k+2,p|(1<>1))continue;

dp[i]=max(dp[i],temp[j]+ans[i]);

}} for(int i=1;i<=nowsize;++i)temp[i]=dp[i];

for(int i=1;i<=nowsize;++i)last[i]=now[i];

lastsize=nowsize; }}

int main()while(true);

n=k;

temp[1]=last[1]=0;

lastsize=1;

dp();

int sum=0;

for(int i=1;i<=lastsize;++i)sum=max(sum,temp[i]);

printf("%d\n",sum);

} return 0;

}

現在對其進行一定程度的優化,上面**310ms,而優化後31ms。

優化分析:

由於該正方形除了相鄰之間不能選之外沒有其他約束條件

所以每一行的狀態以及狀態數其實是一樣的,所以就不用1~n行每次都求該行的狀態以及狀態數

只要求一邊即可,然後把狀態以及狀態數儲存好並且對於狀態i,用鄰接矩陣儲存和狀態i共存的狀態

然後對於第k行第i個狀態,只需要採用鄰接表列舉和i共存的狀態來求dp[k][i]即可 

/*優化分析: 

由於該正方形除了相鄰之間不能選之外沒有其他約束條件

所以每一行的狀態以及狀態數其實是一樣的,所以就不用1~n行每次都求該行的狀態以及狀態數

只要求一邊即可,然後把狀態以及狀態數儲存好並且對於狀態i,用鄰接矩陣儲存和狀態i共存的狀態

然後對於第k行第i個狀態,只需要採用鄰接表列舉和i共存的狀態來求dp[k][i]即可

*/#include #include #include #include #include #include #include #include #include #include #include #define inf 99999999

typedef long long ll;

using namespace std;

const int max=1597+10;

int n,nowsize,size;

int dp[max],temp[max],ans[max],now[max];

int w[16][16],head[max];

char s[max];

struct edge

edge(int v,int next):v(v),next(next){}

}edge[30000];

void init(int n)

void insertedge(int u,int v)

void dfs(int k,int p)

dfs(k+2,p|(1<>1))continue;

insertedge(i,j);

insertedge(j,i);

} }for(int k=1;k<=n;++k)

} for(int i=1;i<=nowsize;++i)temp[i]=dp[i],dp[i]=0; }}

int main()while(true);

init(k);

dp();

int sum=0;

for(int i=1;i<=nowsize;++i)sum=max(sum,temp[i]);

printf("%d\n",sum);

} return 0;

}

HDU2167 狀態壓縮DP

狀態壓縮dp 詳見 1 2 狀態壓縮dp 3dp i j 第i行j狀態的最大和 4dp i j max dp i 1 k sum i j 5題意 給定乙個n n的方格,讓你在裡面取出一些數使其和最大,要求每乙個數不能與其相鄰的8個數同時取出6 7 include8 include 9 include...

HDU 2167 狀態壓縮dp

第一道狀態壓縮dp,其實就是爆搜,只不過把排除了大量不可能的情況,先用sta儲存每行可能的情況,sum i j 儲存i行j種情況的該行和,然後依次更新dp。include include include using namespace std int n,sum 20 1 15 dp 20 1 15...

hdu2167 狀態壓縮DP入門題

照貓畫虎寫了道入門題。講道理這東西我不應該現在才來學tat 狀態壓縮dp入門題 九宮格的相鄰限制條件 n n 3 n 15 dp i j 表示前i行,最後一行狀態為j時得到的最大分數和 對於一行j的所有可能可以用dfs弄出來,在同行搜尋的時候只要保證行不相鄰。在判斷合法狀態轉移的時候,判斷本身 左移...