這道題本來想用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時的分配方法數。狀態轉移方程也很好推 ...