zoukankan      html  css  js  c++  java
  • 解题报告:luogu P3205

    题目链接:P3205 [HNOI2010]合唱队

    跟风切题

    shy txdy!

    手残点了一下标签,看到标签之后就秒了。
    区间 (dp),注意这是整区间不完全利用性的。
    什么意思呢?就是对于继承的区间,里面的元素不一定完全有用。
    还记得 ABC163 的 (E) 题吗?(不记得可以看这里-->快戳我
    有相似之处。
    一般有用的是两端,中点或若干个显而易见的位置。
    我们考虑设 (dp_{i,j,0/1})([i,j])之中最后选左端点/右端点的方案数,显然:

    [dp_{i,j,0}=dp_{i+1,j,0}×[a_{i}<a_{i+1}]+dp_{i+1,j,1}×[a_i<a_j] ]

    [dp_{i,j,1}=dp_{i,j-1,0}×[a_{j}>a_{i}]+dp_{i,j-1,1}×[a_j>a_{j-1}] ]

    最后的得数即为 (dp_{1,n,0}+dp_{1,n,1})

    (Code):

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    
    #define read(x) scanf("%d",&x)
    #define MOD 19650827
    #define ll long long 
    
    int n,a[1005];
    ll dp[1005][1005][3];
    
    int main()
    {
    	read(n);
    	for(int i=1;i<=n;i++) read(a[i]);
    	for(int i=1;i<=n;i++) dp[i][i][0]=dp[i][i][1]=1ll;
    	for(int i=1;i<=n-1;i++)
    	{
    		if(a[i]<a[i+1]) dp[i][i+1][0]=dp[i][i+1][1]=1ll;
    		else dp[i][i+1][0]=dp[i][i+1][0]=0;
    	}
    	for(int i=3;i<=n;i++)
    	{
    		for(int l=1;l+i-1<=n;l++)
    		{
    			int r=l+i-1;
    			if(a[l+1]>a[l]) dp[l][r][0]+=dp[l+1][r][0]%MOD;
    			if(a[r]>a[l]) dp[l][r][0]+=dp[l+1][r][1]%MOD;
    			if(a[l]<a[r]) dp[l][r][1]+=dp[l][r-1][0]%MOD;
    			if(a[r-1]<a[r]) dp[l][r][1]+=dp[l][r-1][1]%MOD;
    		}
    	}
    	printf("%lld
    ",(dp[1][n][0]+dp[1][n][1])%MOD);
    	return 0;
    }
    
  • 相关阅读:
    shared_ptr weak_ptr boost 内存管理
    _vimrc win7 gvim
    qt 拖放
    数学小魔术 斐波那契数列
    qt4 程序 移植到 qt5
    (转)字符串匹配算法总结
    c++11
    BM 字符串匹配
    编译qt5 demo
    c++ 类库 学习资源
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12797620.html
Copyright © 2011-2022 走看看