題目:
不得不說,rqnoj 的機子跑得好慢呀,5*107 的資料範圍本地跑 0.2s,伺服器上愣是把我卡掉了,最後只好寫了乙份 pascal 交上去
本地跑
oj上跑
咳咳,言歸正傳
普通的揹包是求出最優的那一鐘方案,方程轉移是 f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]),相當於把 2 個變數經比較後丟到 1 個變數裡,也就是 k=1時的情況
而現在我們需要求最優的前 k 組方案,那麼可以把陣列再增加一維,變成把 2k 個變數經比較後丟進k個數里,也就是 2 個線性表丟進 1 個線性表裡,由於線性表內資料是單調下降的,則可以按照歸併排序的做法做
實現操作中還可以滾掉第一維,那麼 j 就要遞減列舉
以下是 c++ 的,但是會tle
1 #include2 #include3 #include4 #include5 #include6 #include7這個是 pascal 的,可以acusing
namespace
std;89
const
int v=5001,k=51,maxint=2147483647;10
intf[v][k],g[k];
11int
main()
1230}31
for (i=1;i<=m;i++) ans+=f[s][i];
32 printf("
%d\n
",ans);
33return0;
34 }
1program
xqz;
2uses math;
3const maxv=5000; maxk=51;4
type arr=array[0..maxk] of
longint;
5var
6c,w,i,j,m,n,k,mv,mk,l,r,b,p,e,s,t,v:longint;
7yes:boolean;
8 f:array[0..maxv,0..maxk] of
longint;
9ans,now:int64;
10procedure work(var
a:arr; b,c:arr);
11var
l,r:longint;
12begin
13 l:=1; r:=1;14
while (l+r-2
and ((b[l]<>-1)or(c[r]<>-1)) do
15begin
16while (b[l]<>-1)and((c[r]=-1)or(b[l]>=c[r]+w))and(l+r-2
do17
begin
18 a[l+r-1]:=b[l]; inc(l);
19end;20
while (c[r]<>-1)and((b[l]=-1)or(b[l]<=c[r]+w))and(l+r-2
do21
begin
22 a[l+r-1]:=c[r]+w; inc(r);
23end;24
end;
25end;26
27begin
28readln(mk,mv,n); fillchar(f,sizeof(f),$ff);
29 f[0,1]:=0;30
for i:=1
to n do
31begin
32 readln(c,w); now:=now+c;
33for j:=min(now,mv) downto c do
34 work(f[j],f[j],f[j-c])
35end;36
for k:=1
to mk do
37inc(ans,f[mv,k]);
38writeln(ans);
39close(input); close(output);
40end.
多人揹包問題
爆了。而且是這種半年前刷過的題目。演算法是合併兩個有序的序列,其他的方程之類與單人揹包其實差不多。code include include include include define swap a,b,t define max a,b define min a,b define maxk 55 d...
題目 多人揹包
dd 和好朋友們要去爬山啦!他們一共有 k 個人,每個人都會背乙個包。這些包的容量是相同的,都是 v。可以裝進揹包裡的一共有 n 種物品,每種物品都有給定的體積和價值。在 dd 看來,合理的揹包安排方案是這樣的 每個人揹包裡裝的物品的總體積恰等於包的容量。每個包裡的每種物品最多只有一件,但兩個不同的...
動歸 多人揹包
求01揹包前k優解的價值和 輸入格式 第一行三個數k v n 接下來每行兩個數,表示體積和價值 輸出格式 前k優解的價值和 題解 這道題目是在01揹包的基礎上求出前k個最優解。dp i j 揹包容量為i,第j優解的值。由於任意兩個揹包不能完全相同,所以只初始化dp 0 1 0 因為要求必須恰好裝滿,...