zoj 3725 Painting Storages dp

来源:互联网 发布:淘宝手机怎么装修店铺 编辑:程序博客网 时间:2024/05/09 07:46

最近做题没状态,其实我觉得最大的问题就是没自信,不敢写,还是没有勇气,我发现这都是自己的性格,生活中的我也是这个样子,应该在不断成长!

题目大意:连续的n个点,每个点可以染红色或者蓝色,求连续染m个红色的点的所有方案数。

思路:1、对于连续的第i个点,如果前面已经出现了m个染红色的点,那么对于i+1的话就为ans【i]*2;

             2、对于前面没有出现的点,那么对于第i+1个点,那最后m个就必须出现的,即为a[i-m-1]个,然后减去已经出现的ans【i-m-1】,即为结果!

/////////////////////////////////////////////////////////////////////////// File Name: 3725.cpp// Author: wang// mail: // Created Time: 2013/9/19 9:04:35/////////////////////////////////////////////////////////////////////////#include <cstdio>#include <cstdlib>#include <climits>#include <cstring>#include <cmath>#include <algorithm>#include<iostream>#include<queue>#include <map>using namespace std;typedef long long ll;#define INF (INT_MAX/10)#define SQR(x) ((x)*(x))#define rep(i, n) for (int i=0; i<(n); ++i)#define repf(i, a, b) for (int i=(a); i<=(b); ++i)#define repd(i, a, b) for (int i=(a); i>=(b); --i)#define clr(ar,val) memset(ar, val, sizeof(ar))#define N 100005#define mod 1000000007ll a[N];ll p[N];ll ans[N];int n,m;int main(){a[0]=1;repf(i,1,100000)      a[i]=a[i-1]*2%mod;while(scanf("%d%d",&n,&m)!=EOF){         if(m>n) { printf("0\n"); continue; } memset(ans,0,sizeof(ans)); ans[m]=1;         repf(i,m+1,n) { ans[i]=((ans[i-1]*2+a[i-m-1]-ans[i-m-1])%mod+mod)%mod; }// repf(i,1,n) cout<<ans[i]<<" "; cout<<endl;         cout<<ans[n]<<endl;}return 0;}