codeforces 659 G. Fence Divercity 组合数学 dp

http://codeforces.com/problemset/problem/659/G

思路:

f(i,0/1,0/1) 表示到了第i个,要被切的块开始了没有,结束了没有的状态的方案数

递推看代码:

  //File Name: cf659G.cpp
  //Author: long
  //Mail: [email protected]
  //Created Time: 2016年07月12日 星期二 12时40分28秒

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>

#define LL long long

using namespace std;

const int MAXN = 1000000 + 3;
const int MOD = (int)1e9 + 7;

LL h[MAXN];
LL f[MAXN][2][2];

LL solve(int n){
    h[n+1] = 1;
    memset(f,0,sizeof f);
    f[0][0][0] = 1;
    for(int i=1;i<=n;i++){
        f[i][0][0] = 1;
        (f[i][1][1] = f[i-1][1][1] + h[i] - 1 + f[i-1][1][0] * min(h[i]-1,h[i-1]-1) % MOD) %= MOD;
        (f[i][1][0] = min(h[i],h[i+1]) - 1 + f[i-1][1][0] * min(min(h[i-1]-1,h[i]-1),h[i+1]-1)) %= MOD;
        //printf("i = %d %lld %lld\n",i,f[i][1][0],f[i][1][1]);
    }
    return f[n][1][1];
}

int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++)
            scanf("%d",&h[i]);
        printf("%d\n",(int)solve(n));
    }
    return 0;
}
时间: 2024-10-16 08:44:21

codeforces 659 G. Fence Divercity 组合数学 dp的相关文章

Codeforces 659G Fence Divercity dp

Fence Divercity 我们设a[ i ] 为第 i 个围栏被切的最靠下的位置, 我们发现a[ i ] 的最大取值有一下信息: 如果从i - 1过来并在 i  结束a[ i ] = min(h[ i - 1], h[ i ]) 如果从i - 1过来并延续到i + 1,   a[ i ] = min(h[ i - 1 ], h[ i ], h[ i + 1 ]) 如果从 i 开始 i 结束 a[ i ] = h[ i ] 如果从 i 开始并延续到 i + 1,   a[ i ] = min

codeforces 459E E. Pashmak and Graph(dp)

题目链接: codeforces 459E 题目大意: 给出n个点,m条边的有向图,每个边有边权,求一条最长的边权上升的路径的长度. 题目分析: 定义dp[i]表示第i条边结尾的情况下的最长路径. 定义g[i]表示点i结尾的情况的最长路径. 对所有的边进行排序,那么前面的边只可能小于等于后面的边. 所以dp[i] = g[e[i].u]+1 然后只需要特殊考虑一下边相等的情况,更新g[i]即可,具体见代码. AC代码: #include <iostream> #include <cstr

Codeforces 461B Appleman and Tree(木dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量.保证每一个联通分量有且仅有1个黑色节点.问有多少种切割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的切割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include &l

Codeforces 461B Appleman and Tree(树形dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每个节点的父亲节点,以及每个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量,保证每个联通分量有且仅有1个黑色节点.问有多少种分割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的分割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include <c

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi

codeforces 148E Aragorn&#39;s Story 背包DP

Aragorn's Story Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/148/E Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

【bzoj1925】[Sdoi2010]地精部落 组合数学+dp

题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正 整数. 如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰.位于边 缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边). 类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷. 地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中.地精的酒馆 不论白天黑夜总

Codeforces 67C Sequence of Balls 编辑距离 dp

题目链接:点击打开链接 有一个交换操作比较特殊,所以记录每个点距离自己最近的那个字符的位置 然后交换就相当于把第一行要交换的2个字符 之间的字符都删掉 把第二行要交换的2个字符 之间的字符都插入第一行的2个字符之间 然后再进行交换. #include <cstdio> #include <cstring> #include<iostream> using namespace std; #define inf 10000000 #define N 4005 #define