zoukankan      html  css  js  c++  java
  • AGC050B Three Coins

    做的时候有思考到是否能转化成移动点问题,但是没有清晰的把他解释出来。
    NOIP的时候也一样,T3也有考虑到是否能转为差分,但是也没有清晰的写出来。
    自己做题的时候应尽量保证草稿纸和思绪的清晰,而不是在原地乱撞,思路清晰非常重要。

    考虑如果我们三次操作:

    \(111111 -> 100011\)

    \(111111 -> 110001\)

    易知一定只有这两种操作是有意义的,否则我们不需要重复操作。

    那么我们接着思考,其实操作一等同把开头一个向左移动了3格,操作二等同把末尾一个向右三格。

    接着思考,我们发现,我们可以先选中一个接连的三元组让其中三个元素在保持偏序关系下向左或向右移动三的倍数次。

    那么我们可设计出一个区间dp。

    \(f_{i,j}\)

    两种转移。

    \(i,j\)不是在一个三元组中的开头,末尾端点:那么此时枚举中间点分割序列。

    \(i,j\)是在三元组中的开头,在中间找一个符合三元组同余性质的点,把序列分割中三点两序列。

    #include<bits/stdc++.h>
    #define ll long long 
    #define N 505
    
    int f[N][N];
    int a[N];
    
    int n;
    
    int main(){
    	scanf("%d",&n);
    	for(int i = 1;i <= n;++i)
    	scanf("%d",&a[i]);
    	for(int len = 1;len <= n;++len){
    		for(int l = 1;l + len - 1 <= n;++l){
    			int r = l + len - 1;
    			if((r - l) % 3 == 2){
    				for(int mid = l + 1;mid < r;++mid)
    				if((mid - l) % 3 == 1) 
    				f[l][r] = std::max(f[l][r],a[l] + a[r] + a[mid] + f[l + 1][mid - 1] + f[mid + 1][r - 1]);
    			}
    			for(int mid = l + 1;mid <= r;++mid)
    			f[l][r] = std::max(f[l][r],f[l][mid - 1] + f[mid][r]);
    		}
    	}
    	std::cout<<f[1][n]<<std::endl;
    }
    
    
  • 相关阅读:
    数据库的左右表连接
    数据库索引-索引的优点、缺点、分类、不走索引的情况
    selenium中日期控件的操作方法
    esdoc 自动生成接口文档介绍
    css设置背景图(背景图太大导致图片显示不全)
    k8s调度器及调度队列源码分析
    MIT6.824 2020 Lab1 MapReduce 实现
    git命令
    python3.6、3.9多版本安装共存
    使用蓝鲸平台登录态验证接入第三方系统
  • 原文地址:https://www.cnblogs.com/dixiao/p/15635129.html
Copyright © 2011-2022 走看看