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.