1. 程式人生 > >XTU 1233 Coins(DP)

XTU 1233 Coins(DP)

-a lap eps spa algorithm space comm -- ostream

題意: n個硬幣擺成一排,問有連續m個正面朝上的硬幣的序列種數。

很明顯的DP題。定義狀態dp[i][1]表示前i個硬幣滿足條件的序列種數。dp[i][0]表示前i個硬幣不滿足條件的序列種數。

那麽顯然有dp[i][1]=dp[i-1][1]*2+dp[i-1-m][0].

如果前i-1個硬幣滿足條件,那麽第i個硬幣無論怎麽樣都滿足條件。如果前i-1-m個硬幣不滿足條件,那麽只需要再添加m個正面朝上的硬幣即可。

dp[i][0]=2^i-dp[i][1].

於是最後的答案就是dp[n][1].

技術分享
# include <cstdio>
# include <cstring>
# include 
<cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <set> # include <cmath> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi acos(-1.0) # define eps 1e
-7 # define MOD 1000000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # define mp make_pair # define pb push_back typedef pair
<int,int> PII; typedef vector<int> VI; # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; int Scan() { int x=0,f=1;char ch=getchar(); while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();} while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();} return x*f; } void Out(int a) { if(a<0) {putchar(-); a=-a;} if(a>=10) Out(a/10); putchar(a%10+0); } const int N=1000005; //Code begin... LL dp[N][2], p[N]; void init(){p[0]=1; FO(i,1,N) p[i]=p[i-1]*2%MOD;} int main () { int T, n, m; scanf("%d",&T); init(); while (T--) { scanf("%d%d",&n,&m); mem(dp,0); dp[m][1]=1; dp[m][0]=((p[m]-dp[m][1])%MOD+MOD)%MOD; FO(i,0,m) dp[i][0]=p[i]; FOR(i,m+1,n) dp[i][1]=(dp[i-1][1]*2+dp[i-1-m][0])%MOD, dp[i][0]=((p[i]-dp[i][1])%MOD+MOD)%MOD; printf("%lld\n",dp[n][1]); } return 0; }
View Code

XTU 1233 Coins(DP)