码迷,mamicode.com
首页 > 其他好文 > 详细

[CF] E. Camels

时间:2019-10-26 18:51:33      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:说明   algorithm   space   整数   ret   etc   namespace   趋势   tchar   

CF 2000 的dp题目还是有点难qwq

题意:

一行有\(n\)个空位,每个空位可以填\([1,4]\)的整数,要求:

1.有\(t\)个位置满足 \(ai?1<ai>ai+1(1<i<n)\)

2.有\(t?1\)个位置满足 \(ai?1>ai<ai+1\)

的方案总数

题解:

\(f[i][j][k][0/1]\) 表示 \(i\)位置 当前数是 \(j\) 已经有 \(k\) 个满足条件一的位置 上升/下降趋势

转移:

\[f[i][j][k][0]=\sum f[i-1][l][k][0] + f[i-1][l][k][1] (1<=l<j)\]

\[f[i][j][k][1]=\sum f[i-1][l][k][1] + f[i-1][l][k-1][0] (j<l<=n)\]

\(k = 0\)时说明还没有顶峰,第二个转移的后面这种情况就是0

Code

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
inline int read() {
    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<<3)+(x<<1)+(ch^48); ch=getchar(); }
    return x * f;
}
const int N = 27;
int n,t;
int f[N][N][N][2];  //f[i][j][k][0/1] 表示 i 位置,j高度,k个峰顶,上升/下降 
int main()
{
    n = read(), t = read();
    f[2][4][0][0] = 3;
    f[2][3][0][0] = 2;
    f[2][2][0][0] = 1;
    for(int i=3;i<=n;++i)
        for(int k=0;k<=t;++k)
            for(int j=1;j<=4;++j)
                for(int l=1;l<=4;++l) {
                    if(l < j) f[i][j][k][0] += f[i-1][l][k][0] + f[i-1][l][k][1];   //增加了一个低谷,不改变k
                    if(l > j) f[i][j][k][1] += f[i-1][l][k][1] + (k>0 ? f[i-1][l][k-1][0] : 0);
//                  printf("i = %d %d\n",i,f[i][j][k][1]);
                }
    int ans = 0;
    for(int i=1;i<=4;++i)
        ans += f[n][i][t][1];
    printf("%d",ans);
    return 0;
}

[CF] E. Camels

标签:说明   algorithm   space   整数   ret   etc   namespace   趋势   tchar   

原文地址:https://www.cnblogs.com/BaseAI/p/11744246.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!