1 条题解

  • 0
    @ 2026-8-20 15:33:43

    简要思路

    发掘性质:根据最长上升子序列的 dp 方程有 fi=maxj=1i1fj+1[aj<ai]f_i=\max_{j=1}^{i-1} f_j+1[a_j<a_i],所以插入在 bi,bi+1b_i,b_{i+1} 的数 xx 必须保证 1xmaxj=1ibi+11\le x\le \max_{j=1}^{i}b_i+1,记录 mxi=maxj=1ibimx_i=\max_{j=1}^{i}b_i

    分情况考虑:

    1.存在 mxi+2<bi+1mx_i+2<b_{i+1},无解。

    2.存在不止一个 mxi+2=bi+1mx_i+2=b_{i+1},无解。

    3.只有一个 mxi+2=bi+1mx_i+2=b_{i+1},可以插入一个 mxi+1mx_i+1 以保证合法,但不一定一定要插到 ii 的前一位,统计 ii 前有多少个 jj 满足 bj=mxib_j=mx_i,可以将 mxi+1mx_i+1 插到 jj 后面。

    4.没有 mxi+2=bi+1mx_i+2=b_{i+1}。可以随便插,基本答案即为 i=1nmxi+1\sum_{i=1}^n mx_i+1,但是在如果在 bib_i 左插入 x=bix=b_i 或在 bib_i 右插入 x=bix=b_i,这两种方案得到的 AA 相同,会重复计算,所以答案在最后还要减去 nn,再加上插到最前面一个 11 的答案 11,最终答案为 (i=1nmxi+1)n+1(\sum_{i=1}^n mx_i+1)-n+1

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,a[1000005],maxn[1000005],fl; 
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    	cout.tie(0);
    	cin>>n;
    	for(int i=1;i<n;i++)cin>>a[i];
    	for(int i=1;i<n;i++){
    		maxn[i]=max(maxn[i-1],a[i]);
    		if(maxn[i-1]+2<a[i]){
    			cout<<0;
    			return 0;
    		}if(maxn[i-1]+2==a[i]){
    			if(fl){
    				cout<<0;
    				return 0;
    			}else fl=i;
    		}
    	}
    	long long ans=0;
    	if(fl){
    		for(int i=0;i<fl;i++){
    			if(maxn[i]==a[fl]-2)ans++;
    		}
    		cout<<ans;
    		return 0;
    	}
    	for(int i=1;i<=n;i++){
    		ans+=maxn[i]+1;
    	}
    	ans-=n;ans++;
    	cout<<ans;
    	return 0;
    }
    
    • 1

    [JOISC 2015] 建筑装饰 3 / Building 3

    信息

    ID
    8451
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者