Wikioi 1261 龙王的礼物

http://www.wikioi.com/problem/1261/

继续搬运。。。

用f[i][j]表示前j个数,取出来一些数,他们的和mod n为i时,这个和的最大值.num[i][j]表示这个最大值的情况下,取的最少的块数.a为原数组,则f[i][j]=max(f[i][j-1], f[ ((i-a[j])%n+n)%n ] + a[j])(分别表示不取此数与取此数),当括号内二者相同时,num从前者的num与后者num+1中最小的一个转移而来,否则正常转移.可以使用滚动数组优化空间,否则应该会MLE,数据相当弱,AC并不一定代表代码是完全正确的,注意边界问题

Var i,j,n,m,k:longint;
    lastf,lastg,g,f,a:array[0..100000] of int64;
Begin
  readln(n,m);
  Fillchar(g,sizeof(g),byte(-1));
  For i:=1 to m do readln(a[i]);
  g[0]:=0;
  For i:=1 to m do
  Begin
    lastf:=f; lastg:=g;
    For j:=0 to n-1 do
      Begin
        k:=(j+a[i]) mod n;
        If (lastg[j]<>-1) and ((a[i]+lastf[j]>f[k]) or ((a[i]+lastf[j]=f[k]) and (lastg[j]+1<f[k]))) then
        Begin
          f[k]:=a[i]+lastf[j];
          g[k]:=lastg[j]+1;
        End;
      End;
  End;
  If f[0]<>0 then writeln(f[0],' ',g[0]) else writeln('no answer');
  readln;
End.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值