切换到宽版
  • 4237阅读
  • 0回复

提高组第二题题解 [复制链接]

上一主题 下一主题
离线bj4sj
 
只看楼主 正序阅读 0 发表于: 2006-11-20
终于弄出来了
告别NOI........
高三努力......
大致思路:把zj个主件和m-zj个附件打成num个包,f[i,j]表示处理完前i个主件还剩j元时获得的最大权值
占用内存2232KB

  1. // program NOIP2006_2:Budget
  2. // by bj4sj
  3. const
  4. maxn=3500;
  5. maxm=60;
  6. var
  7. v,w,p:array[1..maxm] of integer;
  8. son:array[1..maxm,1..2] of integer;
  9. fq,jg,qz:array[1..maxm] of integer;
  10. i,zj,num,numm,m:integer;
  11. N,max:integer;
  12. f:array[0..4*maxm,0..maxn] of integer;
  13. procedure init;//输入数据,并转化数据,成为背包问题
  14. var
  15. i,j,k:integer;
  16. begin
  17. assign(input,'budget.in');
  18. reset(input);
  19. read(N,m);
  20. n:=n div 10;
  21. zj:=0;
  22. for i:=1 to m do
  23. begin
  24.   read(v[i],w[i],fq[i]);
  25.   v[i]:=v[i] div 10;
  26.   if fq[i]=0 then
  27.   begin
  28.     inc(zj);//主件个数
  29.     son[zj,1]:=-1;//儿子编号指针
  30.     son[zj,2]:=-1;
  31.     p[zj]:=i;//主件编号指针
  32.   end
  33.   else
  34.   begin
  35.   for k:=1 to zj do if p[k]=fq[i] then fq[i]:=k;
  36.   if son[fq[i],1]=-1 then son[fq[i],1]:=i else son[fq[i],2]:=i;
  37.   end;
  38. end;
  39. num:=0;
  40. for i:=1 to zj do
  41. begin
  42.   inc(num);
  43.   qz[num]:=v[p[i]]*w[p[i]]; //第num个包的权值(只含主件)
  44.   jg[num]:=v[p[i]]; //价格
  45.   for k:=1 to 2 do
  46.   begin
  47.     if son[i,k]<>-1 then
  48.     begin
  49.     inc(num);
  50.     qz[num]:=v[p[i]]*w[p[i]]+v[son[i,k]]*w[son[i,k]]; //第num个包的权值(含主件和第K个附件)
  51.     jg[num]:=v[p[i]]+v[son[i,k]];
  52.     end;
  53.   end;
  54.   if son[i,2]<>-1 then
  55.   begin
  56.     inc(num);
  57.     qz[num]:=v[p[i]]*w[p[i]]+v[son[i,1]]*w[son[i,1]]+v[son[i,2]]*w[son[i,2]];//第num个包的权值(含主件和2个附件)
  58.     jg[num]:=v[p[i]]+v[son[i,1]]+v[son[i,2]];
  59.   end;
  60. end;
  61. close(input);
  62. end;
  63. procedure slove;
  64. var
  65. i,j,k:integer;
  66. tmp:array[1..6] of integer;
  67. begin
  68. for i:=0 to 4*maxm do
  69.   for j:=0 to maxn do f[i,j]:=-20000;
  70. for j:=0 to n do f[0,j]:=0;
  71. num:=0;
  72. for i:=1 to zj do //解决背包问题,每个主件只能选一次.究竟选哪个则需要看tmp[1..6]的大小
  73. begin
  74.   for j:=0 to N do
  75.   begin
  76.     numm:=num;
  77.     for k:=4 to 6 do tmp[k]:=-20000;
  78.     tmp[1]:=f[i-1,j];
  79.     tmp[2]:=f[i,j];
  80.     inc(num);
  81.     tmp[3]:=f[i-1,j+jg[num]]+qz[num];
  82.     if son[i,1]<>-1 then
  83.     begin
  84.     inc(num);
  85.     tmp[4]:=f[i-1,j+jg[num]]+qz[num];
  86.     end;
  87.     if son[i,2]<>-1 then
  88.     begin
  89.     inc(num);
  90.     tmp[5]:=f[i-1,j+jg[num]]+qz[num];
  91.     inc(num);
  92.     tmp[6]:=f[i-1,j+jg[num]]+qz[num];
  93.     end;
  94.     max:=-20000;
  95.     for k:=1 to 6 do
  96.     begin
  97.     if max<tmp[k] then max:=tmp[k];
  98.     end;
  99.     f[i,j]:=max;
  100.     if j<>n then num:=numm;
  101.   end;
  102. end;
  103. end;
  104. begin
  105. init;
  106. slove;
  107. max:=-20000;
  108. for i:=0 to n do
  109. begin
  110.   if max<f[zj,i] then max:=f[zj,i];
  111. end;
  112. assign(output,'budget.out');
  113. rewrite(output);
  114. writeln(max*10:1);
  115. close(output);
  116. end.
[ 此贴被bj4sj在2006-11-20 01:25重新编辑 ]
快速回复
限100 字节
 
上一个 下一个