9.9 天平问题 2720

题目

小C为了试验小X,便为物竞的小X出了一道物理相关的题:现在给出n个质量的砝码,问小X能称出多少种质量的物品,可是总有好事者想要破坏,于是乎,n达到了500,远远超出了小X能够承受的范围,锲而不舍的他决定寻求你们的帮助。

30%:n <=10
60%: n<=100
100%: n<=500 数据保证砝码的质量之和不超过20000

 3                                                  13
 1 
 3
 9

注意:天平有两边,两边均可放。

题解

判定DP,弄一弄就好了。也可以把每个数弄成负数和他自己,然后就是01背包
我居然一次就过了,很惊讶

首先要理解题意,你理解就好,给数据自行理解:
样例输入
3
9
4
20
样例输出
13

可以达到的重量   4    5       7      9    11    13      15     16     20        24       25      29      33
达到方式        4    9-4   20-4-9   9   20-9   4+9   20-9+4   20-4   20   20+4   20+9-4   20+9   20+4+9

f[j]=f[j+a[i]] or f[j-a[i]]
用我这个方法要注意:
为了没有后效性,减和加要分开做
时间复杂度O(20000n)

代码

var
  n,nc,i,j,k,ans:longint;
  f,c:array[0..100200]of boolean;
  a:array[0..500]of longint;

function max(a,b:longint):longint;
begin
  if a>b then exit(a) else exit(b);
end;

procedure qsort(l,r:longint);
var
  i,j,k,t:longint;
begin
  if l>=r then exit;
  i:=l;j:=r;
  k:=a[(l+r) div 2];
  repeat
    while a[i]>k do inc(i);
    while a[j]<k do dec(j);
    if i<=j then
      begin
        t:=a[i];a[i]:=a[j];a[j]:=t;
        inc(i);dec(j);
      end;
  until i>j;
  qsort(i,r);
  qsort(l,j);
end;

begin
  readln(n);
  for i:=1 to n do
    begin
      readln(a[i]);
      nc:=nc+a[i];
    end;
  f[0]:=true;
  qsort(1,n);
  for i:=1 to n do
    begin
      c:=f;
      for j:=1 to nc do
        if f[j+a[i]] then
          f[j]:=true;
      for j:=nc downto 1 do
        if c[j-a[i]] and (j-a[i]>=0) then
          c[j]:=true;
      for j:=1 to nc do
        if c[j] then f[j]:=true;
    end;
  for i:=1 to nc do
    if f[i]=true then inc(ans);
  writeln(ans);
end.


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值