1. 程式人生 > >jzoj P1421【汕頭市選2012初中組】數數(count)

jzoj P1421【汕頭市選2012初中組】數數(count)

題目大意:
求點(1,1)到點(N,M)花費積分為P的路徑的總數。

題解:
f[i,j,k]表示起點到點(i,j)時積分為k的數量。
1<=i,j<=n,0<=k<=p
1.對於一個點f[i,j,k],除了第1行或者第1列以外,都可以從(i-1,j)和(i,j-1)2個點到達。
2.如果f[i-1,j,k]中的的數量不為0,就代表走到第(i-1,j)的時候積分為k的路徑數量為f[i-1,j,k]。如果k+a[i,j]不超過p的話,就把f[i-1,j,k]累加給f[i,j,k+a[i,j]],同理如果f[i,j-1,k]不為0且k+a[i,j]不超過p的話也累加給f[i,j,k+a[i,j]]。
3.取模輸出。

var
     f:array [0..101,0..101,0..2001] of longint;
     a:array [0..101,0..101] of longint;
     i,j,k,n,m,p:longint;
begin
     assign(input,'count.in'); reset(input);
     assign(output,'count.out'); rewrite(output);
     readln(n,m,p);
     for i:=1 to n do
         begin
               for j:=1 to m do
read(a[i,j]); readln; end; if a[1,1]>p then begin writeln('0'); halt; end else f[1,1,a[1,1]]:=1; for i:=2 to m do for j:=0 to p do if f[1,i-1,j]>0 then if a[1
,i]+j<=p then inc(f[1,i,a[1,i]+j]); for i:=2 to n do for j:=0 to p do if f[i-1,1,j]>0 then if a[i,1]+j<=p then inc(f[i,1,a[i,1]+j]); for i:=2 to n do for j:=2 to m do for k:=0 to p do begin if f[i-1,j,k]>0 then if a[i,j]+k<=p then inc(f[i,j,a[i,j]+k],f[i-1,j,k]); if f[i,j-1,k]>0 then if a[i,j]+k<=p then inc(f[i,j,a[i,j]+k],f[i,j-1,k]); f[i,j,a[i,j]+k]:=f[i,j,a[i,j]+k] mod 1000000007; end; writeln(f[n,m,p]); close(input); close(output); end.