[UPC](8838)Secret of Chocolate Poles ---- DP

版权声明:本文为博主原创文章,转载请预先通知博主(〃'▽'〃)。 https://blog.csdn.net/m0_37624640/article/details/82192018

题目链接

Hint: ICPC 2017 Japan Tsukuba

题意:

  •  给你三种圆盘,1.白色薄盘 2.黑色薄盘 3.黑色厚盘。其中白色薄盘和黑色薄盘的厚度为1,黑色厚盘的厚度为k。
  • 现在给你一个高度为l的容器,让你往容器中放圆盘。有以下要求:
  • 1.黑色的圆盘需要在顶部和底部。
  • 2.白色圆盘上面如果有圆盘,必须为黑色圆盘;黑色圆盘上面如果有圆盘,必须为白色圆盘。
  • 3.至少有一个圆盘在容器内。
  • 4.容器内圆盘的高度应该<=l。
  • 现在问你有几种放圆盘的方式?

做法:

  • 自己用列出了k=3时的一些情况(其实列错了),然后发现了组合数(发现错了)。
  • 直接两发组合数规律WA掉QAQ ……没想到这是道DP,(T▽T) 看来要好好练练DP了
  • 那么DP是怎么推的呢?
  • 以l = 5,k = 3为例:
  • 我们dp[i][j]用表示第i层的颜色是j   ,总共有黑白两种颜色,黑色为1,白色为0
  • 我们定义dp[0][0] = 1。因为一开始一定是dp[1][1] = 1。我们在第一层放一个黑色圆盘的方式为1种,那么这个黑色圆盘一定是垒在白色圆盘上的,不如就假设有第0层,放的是白色圆盘,且有一个。
  • 那么怎么转移呢??
  • 你看,根据题意,要放黑色圆盘,那么它的下面一层一定是白色圆盘。所以第i层放黑色圆盘的方式就有
  • ------>  dp[i][1] = dp[i-1][0]
  • 同理:dp[i][0] = dp[i-1][0]
  • 不要忘记我们还有黑色厚盘,厚度为k的这一类
  • 如果i>=k  我们是不是能从(i-k)这个高度的白色圆盘上直接放一个高度为k的黑色厚盘。
  • 即dp[i][1] = dp[i][1]+dp[i-k][0]
  • 最后我们统计dp[i][1]的值就是答案了。

AC代码:

#include<bits/stdc++.h>
#define IO ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define rep(i,s,t) for(int i = (int)(s); i <= (int)(t); i++)
#define rev(i,t,s) for(int i = (int)(t); i >= (int)(s); i--)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define sz(x) (int)(x).size()
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 2e5+5;
const int maxn = 1e4+5;
const int INF = 0x3f3f3f3f;
ll c[105][105];
int main()
{
    #ifdef LOCAL_FILE
    freopen("in.txt","r",stdin);
    #endif // LOCAL_FILE;
    c[0][0] = 1;
    int l,k;
    cin>>l>>k;
    for(int i=1;i<=l;i++)
    {
        c[i][1] = c[i-1][0];
        c[i][0] = c[i-1][1];
        if(i>=k)
        {
            c[i][1]+=c[i-k][0];
        }
    }
    ll ans = 0;
    for(int i=1;i<=l;i++) ans+=c[i][1];
    cout<<ans<<endl;
    return 0;
}
//dp[i][0] = dp[i - 1][ 1 ], dp[i][1] = dp[i - k][0] + dp[i - 1][0] 1代表黑 0代表白

猜你喜欢

转载自blog.csdn.net/m0_37624640/article/details/82192018