計蒜客 NAIPC 2016 F. Mountain Scenes(dp)
阿新 • • 發佈:2018-12-13
題目大意:
一條長為n,寬為1的絲帶,可以剪成多條小絲帶(長度須為整數)。將這些絲帶分配到一個寬為w,高為h的矩形框內(每條絲帶佔寬度為1),絲帶可以不全用上,但不能出現所有絲帶長度都相等的情況(包括0)。並且不能將1條絲帶疊放到另一條絲帶的上方,就是每個寬度只能放一條絲帶。現在給出n,w,h,求出有多少種不同的組合。
題解: 一開始在往排列組合上想,推出如果n>=w*h,那麼結果就是
然後n<w*h的情況,本想用隔板法 ,但是這樣的話就有可能某一段的長度大於h了......
後來看了dalao的部落格才明白是dp......其實看到w,h的範圍是100也多少有點dp的味道的
dp[i][j]代表前i個數,用的絲帶總長度為j的方案數
複雜度為O(nwh)
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define ll long long #define mod 1000000007 using namespace std; ll dp[110][10010]; int main() { int n,w,h; cin>>n>>w>>h; dp[0][0]=1; for(int i=1;i<=w; ++i) for(int j=0; j<=n;++j) for(int k=0;k<=h; ++k) { if(j+k>n)break; dp[i][j+k]+=dp[i-1][j];//當前第i個位置應該放的絲帶長度 if(dp[i][j+k]>mod) dp[i][j+k]-=mod; } ll ans=0; for(int i=0; i<=n; ++i) { ans+=dp[w][i]; if(ans>mod)ans-=mod; } if(n<w*h) ans-=n/w+1; else ans-=h+1; ans=(ans+mod)%mod; cout<<ans<<endl; return 0; }