zoukankan      html  css  js  c++  java
  • 【loj 3271】「JOISC 2020 Day1」建筑装饰 4【DP】

    传送门

    Solution

    首先考虑(mathcal O(n^2)DP)

    (ch[0])(A)数组,(ch[1])(B)数组

    (f[i][j][0/1])表示已经考虑了前(i)位,选了(j)(B)中的数,当前位置选择了(0)(A中的数)或(1)(B中的数),此时是否合法

    易得转移方程为:

    [f[i][j][0]|=f[i-1][j][k]cdot[ch[0][i]>=ch[k][i-1]]\ f[i][j+1][1]|=f[i-1][j][k]cdot[ch[1][i]>=ch[k][i-1]] ]

    因为(f)的值均为(0、1),打表后可以发现对于对于任意的(f[i][j][k]),是(f)(1)(j)一定是连续的一段,考虑开(2)个数组(fl[i][0/1])(fr[i][0/1])表示考虑了前(i)位,当前位置选(0/1)时,合法的(j)的范围

    转移直接取并即可:

    if(fl[i-1][k]>fr[i-1][k]) continue;
    if(ch[0][i]>=ch[k][i-1]) fl[i][0]=min(fl[i][0],fl[i-1][k]),fr[i][0]=max(fr[i][0],fr[i-1][k]);
    if(ch[1][i]>=ch[k][i-1]) fl[i][1]=min(fl[i][1],fl[i-1][k]+1),fr[i][1]=max(fr[i][1],fr[i-1][k]+1);
    

    至于输出方案,我们直接从末位置出发反过来向前枚举当前答案是怎么转移过来的即可

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6+10;
    const int M=4e3+10;
    const int inf=0x3f3f3f3f;
    int n,ch[2][N],s[N][2],fl[N][2],fr[N][2];
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=2*n;++i) scanf("%d",&ch[0][i]);
    	for(int i=1;i<=2*n;++i) scanf("%d",&ch[1][i]);
    	fl[0][0]=fr[0][0]=0;
    	fl[0][1]=fr[0][1]=0;
    	for(int i=1;i<=2*n;++i){
    		fl[i][0]=inf;fr[i][0]=-inf;
    		fl[i][1]=inf;fr[i][1]=-inf;
    		for(int k=0;k<=1;++k){
    			if(fl[i-1][k]>fr[i-1][k]) continue;
    			if(ch[0][i]>=ch[k][i-1]) fl[i][0]=min(fl[i][0],fl[i-1][k]),fr[i][0]=max(fr[i][0],fr[i-1][k]);
    			if(ch[1][i]>=ch[k][i-1]) fl[i][1]=min(fl[i][1],fl[i-1][k]+1),fr[i][1]=max(fr[i][1],fr[i-1][k]+1);
    		}
    	}
    	int now=-1;
    	if(fl[2*n][0]<=n&&n<=fr[2*n][0]) now=0;
    	else if(fl[2*n][1]<=n&&n<=fr[2*n][1]) now=1;
    	if(now==-1){puts("-1");return 0;}
    	vector<int> ve;
    	int sum=n;
    	for(int i=2*n;i>=1;--i){
    		ve.push_back(now);
    		if(now==1) --sum;
    		for(int k=0;k<=1;++k){
    			if(fl[i-1][k]>sum||fr[i-1][k]<sum) continue;
    			if(ch[now][i]>=ch[k][i-1]){
    				now=k;
    				break;
    			}
    		}
    	}
    	for(int j=ve.size()-1;j>=0;--j) printf("%c",ve[j]+'A');
    	return 0;
    }
    
  • 相关阅读:
    Discuz! X3 全新安装图文教程
    https://blog.csdn.net/doegoo/article/details/50749817
    docker 网络
    Docker的网络类型和固定IP设置
    docker lamp
    MongoDB分片搭建
    iptables原理及使用教程
    VNC服务安装、配置与使用
    ssh免密码登陆
    nmap
  • 原文地址:https://www.cnblogs.com/tqxboomzero/p/14254605.html
Copyright © 2011-2022 走看看