1. 程式人生 > >1857. 最大值 (Standard IO)

1857. 最大值 (Standard IO)

Description

  找到一個數組的最大值的一種方法是從陣列開頭從前到後對陣列進行掃描,令max=a0,如果a[i]>max,就更新max,這樣就可以在O(N)的時間裡找到一個數組的最大值。
  這個問題是相當簡單的,但是想到了另一個問題,如果一個包含N個元素的陣列a裡面的元素的值是在1…K之間的整數,存在多少個不同的陣列a,進行了如上掃描之後,max恰好進行了P次更新?
  下面是N = 4,K = 3,P = 2時所有情況
  1) {1,1,2,3}
  2) {1,2,1,3}
  3) {1,2,2,3}
  4) {1,2,3,1}
  5) {1,2,3,2}
  6) {1,2,3,3}
  共有6種情況
  由於答案可能很大,所以你僅僅需要把答案mod (10^9+7)輸出。

Input

  輸入檔案findmax.in的第一行T,本題有T組資料。
  接下來T行,每行三個整數N,K,P

Output

  輸出檔案findmax.out包括T行,每行一個答案。

Sample Input

3

4 3 2

2 3 1

3 4 1

Sample Output

6

3

30

【資料規模】

30%資料 T=1;1 <= n <= 10;1 <= K <= 2;0 <= P < n
60%資料 T=1;1 <= n <= 50;1 <= K <= 10;0 <= P < n
100%資料1 <= T <= 100;1 <= n <= 100;1 <= K <= 300;0 <= P < n

題解:

  f[i,j,k]表示前i個用了j個數字有k次更新
  f[i,j,k]:=(f[i,j,k]+f[i-1,j,k]*j) mod 1000000007;
  //新加的數字小於等於前一個數字,不更新。
  f[i,j,k]:=(f[i,j,k]+s[i-1,j-1,k-1]) mod 1000000007;
  //新加的數字大於前一個數字,更新。
  s[i,j,k]:=(s[i,j,k]+f[i,j,k]+s[i,j-1,k])mod 1000000007;
  //s[i,j,k]表示之前a的所有的數。

程式碼:

const
  maxn=1000000007;
var
  f,s:array[0..100,0..300,0..100] of int64;
  a:array
[0..100,1..3] of longint; x,y,z,n:longint; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; var i,j,k:longint; ans:int64; begin readln(n); for i:=1 to n do begin readln(a[i,1],a[i,2],a[i,3]); x:=max(x,a[i,1]); y:=max(y,a[i,2]); z:=max(z,a[i,3]); end; for i:=1 to y do begin f[1,i,0]:=1; s[1,i,0]:=i; end; for i:=2 to x do for j:=1 to y do for k:=0 to min(z,i-1) do begin f[i,j,k]:=(f[i,j,k]+f[i-1,j,k]*j) mod maxn; if k<>0 then f[i,j,k]:=(f[i,j,k]+s[i-1,j-1,k-1]) mod maxn; s[i,j,k]:=(s[i,j,k]+f[i,j,k]+s[i,j-1,k])mod maxn; end; for i:=1 to n do begin ans:=0; for j:=1 to a[i,2] do ans:=(ans+f[a[i,1],j,a[i,3]]) mod maxn; writeln(ans); end; end.