gym 101194 china final Problem H. Great Cells(數學,想法題,好題)
Problem H. Great Cells
Input file:
Output file:
Time limit:
Standard Input
Standard Ouptut
2 seconds
Mr. Panda likes playing puzzles with grid paper. Recently he invented a new rule to play withthe grid paper.
At the beginning, he grabs a grid paper with N rows and M columns. Then he fills each cell aninteger in the range of [1
• The value in the cell is
strictly
larger than other cells in the same row.
• The value in the cell is
strictly
larger than other cells in the same column.
Now Mr. Panda is wondering how many different ways he can fill the grid paper so that there areexactly g Great cells.
As Mr. Panda likes simple conclusion number, let’s just tell him the value
g=0
Ag
represents the number of different ways Mr. Panda can fill the grid paper such that there are
exactly
The first line of the input gives the number of test cases,
T.
T lines follow.
Each line represents a test case containing 3 integers N,
M representing the number of rows and
columns of the grid paper, K representing the range for filling numbers.Output
For each test case, first output one line containing “Case #x: y”, where x is the test case number(starting from 1), y is the simple conclusion number for Mr. Panda.
Limits
• 1
≤ T
≤ 20.
• 1≤N,M,K≤200.
NM
∑9(g+1)·Ag mod (10 +7)
Page 11 of 21
The 2016 ACM-ICPC Asia China-Final Contest
Sample input and output
Note
Forthefirstsample,A0 =10,A1 =4,A2 =2,A3 =A4 =0,thustheansweris10+4×2+2×3=24.
題意:
給出n,m,k,在n*m的網格內填[1,k]的整數,定義一個格子是great的,如果滿足填在這個格子中的數是本行和本列中嚴格的最大值。定義A-g為網格中恰好有g個great格子的填法數,求Σ(g+1)A-g。
題解:
這題乍一看需要用組合數學 容斥原理計算A-g,但是這樣做比較麻煩複雜。但其實這題是(g+1)的套路。。。簡便做法是觀察整體,把問題轉化成每個位置是great格子對最終答案的貢獻和,這樣就繞開了A-g的計算。
首先,考慮整體的填法:K^(M×N)——這個是容易計算的,那麼我們先企圖用整體填法數化簡待求式!我們發現將待求式展開,後面的ΣA-g的和便是整體的填法數。(一般都需要先拿整體化簡一把!)
於是現在只需著手計算Σg*A-g,這個就用貢獻和的思想轉化,因為有g個great格的填法數乘了個g相當於攤到了這g個位置上,也就是說每個great格獨立了,也即每一個格是great格對Σg*A-g貢獻=使這個格是great的所有填法總數:
Contrib=Σ(i=1到i=K-1)i^(N-1+M-1)×K^[(N-1)×(M-1)] (轉化為貢獻和,有點智力題的感覺orz..)
這裡注意一點:以上公式沒有考慮n=m=1的情況,因為這時填1也算是great格(而以上公式從填2開始考慮的)
從而最後
ans=Contrib×N×M+K^(M×N)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const int inf=0x3fffffff;
const ll mod=1000000007;
const int maxn=20+10;
ll fpow(int p,int x)
{
ll ans=1,t=p;
while(x)
{
if(x&1) ans=(ans*t)%mod;
t=(t*t)%mod;
x/=2;
}
return ans;
}
int main()
{
int cas;
scanf("%d",&cas);
rep(kase,1,cas+1)
{
ll ans=0;
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
rep(i,1,k)
{
ll res=fpow(i,n-1+m-1);
ans=(ans+res)%mod;
}
ans=(ans*fpow(k,(n-1)*(m-1)))%mod;
ans=ans*n%mod*m%mod;
ans=(ans+fpow(k,n*m))%mod;
if(n==1&&m==1) ans=(ans+1)%mod;
printf("Case #%d: %I64d\n",kase,ans);
}
return 0;
}