Codeforces Beta Round #14 (Div. 2) E. Camels 题解

269 阅读1分钟

思路

四维dp。设f[i][j][k][0/1]f[i][j][k][0/1]为第ii个点高度为jj,属于第kk个驼峰(包含上升段和下降段,峰属于上升段,谷属于下降段),00代表位于上升段,11代表位于下降段。

显然状态转移方程为

f[i][j][k][0]=r=j+14f[i1][r][k][0]+f[i1][r][k][1]f[i][j][k][1]=r=1j1f[i1][r][k][1]+f[i1][r][k1][0]f[i][j][k][0]=\sum\limits_{r=j+1}^4f[i-1][r][k][0]+f[i-1][r][k][1]\\ f[i][j][k][1]=\sum\limits_{r=1}^{j-1}f[i-1][r][k][1]+f[i-1][r][k-1][0]

边界设为i=2i=2的时候,对各个高度以此计算赋值即可。

代码

#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define en puts("")
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll> 
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
void read() {}
void OP() {}
void op() {}
template <typename T, typename... T2>
inline void read(T &_, T2 &... oth)
{
    int __=0;
    _=0;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')
            __=1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        _=_*10+ch-48;
        ch=getchar();
    }
    _=__?-_:_;
    read(oth...);
}
template <typename T>
void Out(T _)
{
    if(_<0)
    {
        putchar('-');
        _=-_;
    }
    if(_>=10)
       Out(_/10);
    putchar(_%10+'0');
}
template <typename T, typename... T2>
inline void OP(T _, T2... oth)
{
	Out(_);
	putchar('\n');
	OP(oth...);
}
template <typename T, typename... T2>
inline void op(T _, T2... oth)
{
	Out(_);
	putchar(' ');
	op(oth...);
}
/*#################################*/
const ll N=11;
ll n,t,ans;
ll f[N<<1][6][N][2];
int main()
{
	read(n,t);
	f[2][2][1][1]=1;
	f[2][3][1][1]=2;
	f[2][4][1][1]=3;
	rep(i,3,n)
	{
		rep(k,1,t)
		{
			rep(j,1,4)
			{
				rep(r,j+1,4)
					f[i][j][k][0]+=f[i-1][r][k][0]+f[i-1][r][k][1];
				rep(r,1,j-1)
					f[i][j][k][1]+=f[i-1][r][k][1]+f[i-1][r][k-1][0];
			}
		}
	}
	ll ans=0;
	rep(i,1,4)
		ans+=f[n][i][t][0];
	op(ans);
}