【hihocoder 1651】2017-12-3 小球染色
時間限制:10000ms
單點時限:1000ms
內存限制:256MB
描述
小Ho面前有N個小球排成了一排。每個小球可以被染成M種顏色之一。
為了增強視覺效果,小Ho希望不存在連續K個或者K個以上的小球顏色一樣。
你能幫小Ho計算出一共有多少種不同的染色方法麽?
例如N=4, M=2, K=3,則有10種染色方法:
0010 0011 0100 0101 0110 1001 1010 1011 1100 1101
輸入
三個整數:N, M和K。
對於30%的數據, 1 ≤ N, M, K ≤ 100
對於60%的數據,1 ≤ N, M, K ≤ 300
對於100%的數據,1 ≤ N, M, K ≤ 1000
輸出
一個整數表示答案。註意方法數可能非常大,你只需要輸出模
樣例輸入
4 2 3
樣例輸出
10
#題解:
如果只有一個小球,染色的方案是m。如果有兩個小球,允許連續一次則有m(m-1)種方案,兩次為m。
例:如果n=4, 顏色m=3, 連續上限k=3。m=3不變, 設方案數為e(n, m), 代表長度為n,最大連續長度恰好為m的結果
則:
n =1, e(1,1) = 3
n = 2, e(2,1)=3*2=6,e(2,2)=e(1,1)=3 (e(n,m) =e(n-1,m-1),從e的意義上看出來,把多出來的1個小球加到一個長度為m-1的連續串裏)
n = 3, e(3,1)=6*2+3*2=18, 這裏可以看到e(3,1)=∑(1,k)e(2,d) * (m-1),因為對e(n-1,X)種代表的小球串染色方案,每個都可以把串拿來加長, 每個對應的方案數恰好是m-1種。至於為什麽是m-1種,並不能解釋,猜測是n-1, X連續的小球染色剛好可以對應一個n,1連續的小球染色。
按照分析這種染色的慣例,一般是不會把顏色作為可變變量的,因為在可變大小的區間裏進行顏色分配意味著位置、顏色、連續方向都要考慮,並不是很便於編程。
考慮隨著長度增加,連續上限的增加,顏色的方案數。用動態規劃的方法來做。
代碼:
#include <bits/stdc++.h> using namespace std; const int N = 1000; const int MOD = (int)1e9 + 7; long long dp[N + 1][N + 1]; int main() { int n, m, k; scanf("%d %d %d", &n, &m, &k); dp[1][1] = m; for (int i = 2; i <= n; ++i) { for (int j = 1; j < k; ++j) { dp[i][1] = (dp[i][1] + dp[i - 1][j] * (m - 1) % MOD) % MOD; } for (int j = 2; j < k ; ++j) { dp[i][j] = dp[i - 1][j - 1]; } } long long res = 0; for (int i = 1; i < k; ++i) { res = (res + dp[n][i]) % MOD; } #ifdef __DEBUG__ for (int i = 1; i <= n; i++) { for (int j = 1; j < k; j++) { printf("%lld ", dp[i][j]); } printf("\n"); } #endif printf("%lld\n", res); return 0; }
測試:
【hihocoder 1651】2017-12-3 小球染色