F. Mountain Scenes dp The North American Invitational Programming Contest 2016
阿新 • • 發佈:2018-12-13
題意:
給定n個1*1的小正方形,一個w * h 的框子,任意放置,符合物理上的上下規則;問有多少种放置方法
思路:
開始想的是按層dp;事實上是不行的,複雜度很高,
然後想到了按列dp,這樣我們還需要有一維表示用了多少個小正方形,
所以得到dp方程: dp[i][j] 表示前i行,一共用了j個的所有種類數
在求解dp[i][j] 時:列舉第i列放置的個數 k,dp[i][j] = sigma dp[i-1][j-k] k∈(0, h);
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 110; const int maxd = 1e4+10; const ll mod = 1e9 + 7; int n, w, h; ll dp[maxn][maxd] ={0}; int main() { scanf("%d%d%d", &n, &w, &h); for(int i = 0; i <= h; ++i) { dp[1][i] = 1; } int m; for(int i = 1; i <= w; ++i) { m = i*h + h; for(int j = 0; j <= n && j <= m; ++j) { for(int k = 0; k <= h; ++k) { if(j-k < 0) break; dp[i+1][j] = (dp[i+1][j] + dp[i][j-k]) % mod; } } } ll ans = 0; for(int i = 1; i <= n; ++i) { ans = (ans + dp[w][i]) % mod; } ans = (ans - min(h, n/w) + mod) % mod; printf("%lld\n", ans); return 0; }