给出一个N行3列的非负数矩阵的各行各列之和,统计满足条件的矩阵数量之和,答案mod 10^17。
输入:{dy}行包含4个正整数n,c1,c2,c3分别代表行数,及列1列2列3之和,第二行n个整数代表各行各列3个数之和,每行每列之和不超过125.
样例
3 2 3 4
1 2 6
输出
17
思路是DP,f[h,x,y]代表的是第h横行,{dy}列和为x,第二列和为y的情况数(因为x,y已确定,所以z也确定了)。此处h可以用滚动数组降维f[0..1,x,y].注意充分利用条件减少决策量
我的标程在学校明天发
program matrix;
const
maxn=201;
mn=100000000000000000;
var
f:array[-1..maxn,-1..125,-1..125] of int64;
s:array[-1..maxn] of longint;
hen,hen2:array[-1..maxn] of longint;
zon,zon2:array[1..4] of longint;
n:longint;
ans:int64;
procedure datain;
var
i,j:longint;
begin
assign(input,'matrix.in');reset(input);
assign(output,'matrix.out');rewrite(output);
readln(n,zon[1],zon[2],zon[3]);
for i:=1 to n do
read(hen[i]);
ans:=0;
fillchar(s,sizeof(s),0);
s[0]:=0;
for i:=1 to n do
s[i]:=s[i-1]+hen[i];
end;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure dfs(z,h:longint);
var
i,j:longint;
begin
if z=4 then
begin
if hen[h]=hen2[h] then
dfs(1,h+1);
exit;
end;
if h=n+1 then
begin
inc(ans);
ans:=ans mod 100000000000000000;
exit;
end;
for i:=0 to min(hen[h]-hen2[h],zon[z]-zon2[z]) do
begin
hen2[h]:=hen2[h]+i;
zon2[z]:=zon2[z]+i;
dfs(z+1,h);
hen2[h]:=hen2[h]-i;
zon2[z]:=zon2[z]-i;
end;
end;
procedure dp;
var
i,j,k,x,y,z:longint;
begin
fillchar(f,sizeof(f),0);
f[0,0,0]:=1;
for k:=1 to n do
for i:=0 to min(zon[1],s[k]) do
for j:=max(0,s[k]-zon[3]-i) to min(s[k]-i,zon[2]) do
begin
for x:=0 to min(i,hen[k]) do
for y:=0 to min(hen[k]-x,j) do
{if i-x>=0 then
if j-y>=0 then
if x+y<=hen[k] then}
f[k,i,j]:=(f[k-1,i-x,j-y]+f[k,i,j]) mod mn;
end;
writeln(f[n,zon[1],zon[2]]);
end;
begin
datain;
{if n<4 then
begin
dfs(1,1);
writeln(ans);
end
else} dp;
close(input);
close(output);
end.