这是一道naipc里的题,题目链接:https://vjudge.net/contest/313660#problem/F
An artist begins with a roll of ribbon, one inch wide. She clips it into pieces of various integral lengths, then aligns them with the bottom of a frame, rising vertically in columns, to form a mountain scene. A mountain scene must be uneven; if all columns are the same height, it’s a plain scene, not a mountain scene! It is possible that she may not use all of the ribbon. If our artist has 4 inches of ribbon and a 2 × 2 inch frame, she could form these scenes: She would not form these scenes, because they’re plains, not mountains! Given the length of the ribbon and the width and height of the frame, all in inches, how many different mountain scenes can she create? Two scenes are different if the regions covered by ribbon are different. There’s no point in putting more than one piece of ribbon in any column.
Input
Each input will consist of a single test case. Note that your program may be run multiple times on different inputs.
The input will consist of a single line with three space-separated integers n, w and h, where n (0 ≤ n ≤ 10,000) is the length of the ribbon in inches, w (1 ≤ w ≤ 100) is the width and h (1 ≤ h ≤ 100) is the height of the frame, both in inches. North American Invitational Programming Contest 2016
Output
Output a single integer, indicating the total number of mountain scenes our artist could possibly make, modulo 109 + 7.
Sample
Input
1
Sample
Output
1 25 5 5 7770
Sample
Input
2
Sample
Output
2 15 5 5 6050
Sample
Input
3
Sample
Output
3 10 10 1 1022
Sample
Input
4
Sample
Output
4 4 2 2 6
题解:
前半段总结了一下规律,但能力有限没有总结出一个简洁的规律可以概括所有情况,只能概括n>=w*h的情况,以后能力强了应该会回过头来看看
#include<stdio.h>
#include<math.h>
typedef long long ll;
const ll mo=1e9+7;
ll quick(ll a,ll n,ll m)
{
ll ans=1;
while(n)
{
if(n&1)
{
ans=(ans*a)%m;
}
a=(a*a)%m;
n>>=1;
}
return ans;
}
int min(int a,int b){return a<b?a:b;}
ll dp[10010];
int main()
{
int n,w,h,i,j,k;
ll ans;
scanf("%d%d%d",&n,&w,&h);
if(n>=h*w)ans=(quick(h+1,w,mo)-h-1+mo)%mo;
else
{
dp[0]=1;
for(i=1;i<=w;i++)
for(j=n;j>=0;j--)
for(k=1;k<=h&&j-k>=0;k++)
dp[j]=(dp[j]+dp[j-k])%mo;
ans=mo-min(h+1,n/w+1);
for(i=0;i<=n;i++)ans=(ans+dp[i])%mo;
}
printf("%lld",ans);
return 0;
}