POJ 1018(DP 滾動陣列)

2021-06-22 13:39:45 字數 1583 閱讀 9231

這道題本來想用map儲存price所能達到的最大bandwidth,各種tle之後看了discuss,得知雖然price可能很大,但bandwidth卻範圍有限,於是對bandwidth用了滾動陣列dp

考慮:用pre[b]=p表示為標號為i-1的裝置選好製造商後達到的總頻寬為b時的最小**,對於標號為i的裝置來說,有m個製造商,頻寬、**分別為band[m],price[m],可以得出如下的偽**:

for device = 1 : n

for(i = 0; i < m; ++i)

for each b in bandwidthreachedbypre

b = min(b, band[i]);

if b not in bandwidthreachedbycur

bandwidthreachedbycur.add(b);

cur[b] = pre[b] + price[i];

else

cur[b] = min(cur[b], pre[b] + price[i]);

bandwidthreachedbypre = bandwidthreachedbycur;

bandwidthreachedbycur.clear();

pre = cur;

cur.clear();

best = 0

for each b in bandwidthreachedbypre

best = max(best, b/pre[b]);

return best;

用陣列下標代替map儲存,再用陣列下標實現交換滾動可以寫出如下**:

#include #include using namespace std;

#define inf 9999

int bandwidthreached[2][5000], bandcount[2];//bandwidth小於5000

int costforband[2][5000] = ;

int main()

else

costforband[cur][b] = min(costforband[cur][b], costforband[pre][b] + price);}}

//swap and reset cur

swap(pre, cur);

for(j = 0; j < bandcount[cur]; ++j)

costforband[cur][bandwidthreached[cur][j]] = 0;

bandcount[cur] = 0;

}//select best

float best = 0.0f;

for(j = 0; j < bandcount[pre]; ++j)

printf("%.3f\n", best);

//reset pre

for(j = 0; j < bandcount[pre]; ++j)

costforband[pre][bandwidthreached[pre][j]] = 0;

}return 0;

}

poj1159 dp 滾動陣列

如題 給出乙個字串和它的長度,要求輸出最少要加幾個字母這個字串變成回文串。增加回文串的數量 字串長度 字串和它的逆序的最長公共子串行的長度。字串長5000 如果開dp肯定超記憶體,可以使用short定義陣列。不難發現,dp的狀態轉移方程dp i j max dp i 1 j dp i j 1 或dp...

POJ 1157 邊輸入邊DP 滾動陣列

用dp i j 表示將flower i放在vase j中 這個狀態 所能達到的最大美感值,假設flower i放入各個vase中的美感值分別為fv 1 fv v 則 for cur i v dp i cur inf for pre i 1 cur 1 dp i cur max dp i 1 pre ...

poj 2441 狀態壓縮 滾動陣列 剪枝DP

題意 有n 20 只牛和m 20 個籃球場,每個籃球場只能乙隻牛打,然後每只牛都有自己喜好的籃球場。現在問有多少種分配方法使得每只牛都能在自己喜歡的籃球場打球,並且這個球場只有它乙隻牛。解析 首先是狀壓 dp i state 表示的是第i隻牛球場狀態為state時的分配方法數。狀態轉移方程也很好推 ...