日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu 1565 方格取数(1)(状态压缩dp)

發(fā)布時間:2025/3/16 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 1565 方格取数(1)(状态压缩dp) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

方格取數(shù)(1)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Time Limit: 10000/5000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)

Problem Description 給你一個n*n的格子的棋盤,每個格子里面有一個非負數(shù)。
從中取出若干個數(shù),使得任意的兩個數(shù)所在的格子沒有公共邊,就是說所取的數(shù)所在的2個格子不能相鄰,并且取出的數(shù)的和最大。
Input 包括多個測試實例,每個測試實例包括一個整數(shù)n 和n*n個非負數(shù)(n<=20)
Output 對于每個測試實例,輸出可能取得的最大的和
Sample Input 3 75 15 21 75 15 28 34 70 5
Sample Output 188


分析:dp[i][j]表示前i行,第i行取第j個狀態(tài)時的取值總和,則dp[i][j] = max(dp[i][j], dp[i-1][k] + sum[i][j]).其中sum[i][j]表示第i行取第j個狀態(tài)的取值總和。

因為n<=20,經(jīng)計算可以發(fā)現(xiàn),合法狀態(tài)最多有17711個。

#include <cstdio> #include <cstring> #include <algorithm> using namespace std;const int N = 21; const int M = 17720; //合法狀態(tài)最多有17711個 int n, p; int a[N][N]; int dp[N][M]; int s[M]; int sum[N][M];bool checkA(int x) { //判斷本行狀態(tài)是否沖突return !(x & (x >> 1)); }bool checkB(int x, int y) { //判斷本行和上一行是否沖突return !(x & y); }int get_sum(int r, int state) { //求第i行狀態(tài)為state時的取值總和int res = 0;for(int i = 0; i < n; i++)if((state >> i) & 1)res += a[r][n - 1 - i];return res; }void Init() {p = 0;memset(sum, 0, sizeof(sum));for(int i = 0; i < (1 << n); ++i) //求出所有合法狀態(tài)if(checkA(i))s[p++] = i;for(int i = 0; i < n; ++i) { //求第i行取第j個狀態(tài)時的取值總和for(int j = 0; j < p; ++j) {sum[i][j] = get_sum(i, s[j]);}} }void solve() {memset(dp, 0, sizeof(dp));for(int i = 0; i < p; i++)dp[0][i] = sum[0][i];for(int i = 1; i < n; i++) { //行數(shù)for(int j = 0; j < p; j++) { //本行狀態(tài)for(int k = 0; k < p; k++) { //上一行的狀態(tài)if(checkB(s[j], s[k])) {dp[i][j] = max(dp[i][j], dp[i-1][k] + sum[i][j]);}}}}int ans = dp[n-1][0];for(int i = 1; i < p; i++)if(ans < dp[n-1][i])ans = dp[n-1][i];printf("%d\n", ans); }int main() {while(~scanf("%d", &n)) {for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)scanf("%d", &a[i][j]);Init();solve();}return 0; }

總結(jié)

以上是生活随笔為你收集整理的hdu 1565 方格取数(1)(状态压缩dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。