首先,最樸素的思想為暴搜所有解o(2^n)不可接受;
已d[ i ] [ j ] 代表前 i 個數字 裡 已作出選擇後產生的序列記為 j ,j 最大為 (16,8,4,2全部除以壓縮一下) 4000; 注意 j 儲存的是乙個序列經產生所屬運算後最後的遞減數數列; 舉個栗子 : 14(8 4 2) 當添入 2 變為 16, 添入 4 變為 4 ,填入1變為 15;
這樣狀態總數約二百萬,加上剪枝(當j > sum(i)(sum(i) 為前 i 個寶藏的和) 可剪枝 ),已經足夠快;
這樣 i 的狀態依賴有 i - 1可轉移至它 的狀態;可使用刷表法;
#include #include #include #include using namespace std;
const int maxn = 505;
const int maxm = 4010;
int a[maxn],n,d[maxn][maxm],sum[maxn];
int getnum(int s,int& s0)
int temp = log2(s0);
int res=0;
for(int i=0;i<=12;i++)
d[0][0]=0;
for(int i=0;isum[i]) break;
if(d[i][j]==-1) continue;
d[i+1][j]=max(d[i+1][j],d[i][j]);
int tt = a[i+1];
int fen = getnum(j,tt);
d[i+1][tt] = max(d[i+1][tt],d[i][j]+a[i+1]+fen);
}int res=0;
for(int i=0;isum[n]) break;
res=max(res,d[n][i]);
}printf("%d\n",res*2);
} return 0;
}
zoj3755 狀態壓縮dp
很久沒有1a了 爽 題目也是很常規的狀態壓縮題目,這類題目一般都是預處理所有狀態,然後通過列舉,判斷是否符合要求,再從符合要求的末狀態中找到答案即可。這個題目,由於給定的是所有偶數列,那麼,可以想到,每一列只跟左右兩列有關,其他列對其沒有影響。因此,只需要確定了兩列中的一列的狀態,另外一列便可以列舉...
zoj 3471 狀態壓縮dp
題目大意 不超過10種氣體,兩兩之間相互碰撞可以產生一定的能量,如a碰b,那麼b氣體就消失,自身不能碰自身,問最後所能得到的最大能量。題目解析 用10位二進位制表示氣體是否存在,0表示存在,1表示不存在,s 上乙個狀態 中的兩種氣體碰撞並且有一種消失,可以得到news的狀態 狀態轉移 狀態表示 dp...
ZOJ2563 之狀態壓縮dp
long dominoes time limit 2 seconds memory limit 65536 kb find the number of ways to tile an m n rectangle with long dominoes 3 1 rectangles.each domin...