题意:有一个竖直放置的高度为l cm的盒子,现在有三种方块分别为1cm的白块,1cm的黑块,k cm的黑块,要求第一块放进去的必须是黑色的,盒子最上边的必须也是黑色的,盒子不必放满,问一共有多少种放法。
思路:知道要用DP确实死活推不出状态转移公式来,这就很窒息了。到网上搜了一下题解,,,,,,还是自己太low了。
二维DP,第一维表示盒子的高度,第二维表示当前是放白块还是黑块。0表示白块,1表示黑块即:(白块是不会影响放的种类的数目的)
当高度还不到k cm时:dp[i][0] = dp[i][1], dp[i][1] = dp[i][0] ;
当高度大于k cm时:dp[i][0] = dp[i][1], dp[i][1] = dp[i][0] +dp[i-k][0];
代码:
1 /* 2 Time:2018/9/7 3 Writer:Sykai 4 Function:Secret of Chocolate Poles 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <algorithm> 9 #include <set> 10 #include <cstring> 11 #include <queue> 12 #define INF 0x3f3f3f3f 13 #define MIN(a,b) a<b ? a : b 14 #define FRE() freopen("in.txt","r",stdin) 15 using namespace std; 16 const int maxn = 110; 17 const int MOD = 1e9 + 7; 18 typedef long long ll; 19 typedef pair<int, int> P; 20 ll dp[maxn][2]; 21 22 23 int main(){ 24 int l,k; 25 while(scanf("%d%d",&l,&k)!=EOF){ 26 dp[0][0] = 1; 27 for(int i = 1; i<=l; i++){ 28 dp[i][1] = dp[i-1][0]; 29 dp[i][0] = dp[i-1][1]; 30 if(i>=k) dp[i][1] = dp[i-1][0]+dp[i-k][0]; 31 } 32 ll ans = 0; 33 for(int i = 1; i<=l; i++){ 34 ans += dp[i][1]; 35 } 36 printf("%lld ",ans); 37 } 38 return 0; 39 }