Wikioi 1261 龙王的礼物

来源:互联网 发布:如何计算停电天数java 编辑:程序博客网 时间:2024/04/29 12:06

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
原创粉丝点击