DPL_1_D:Longest Increasing Subsequence[贪心+二分][动态规划]

本文介绍了一种求解最长上升子序列(LIS)问题的高效算法。通过使用贪心思想和二分查找技巧,避免了传统DP方法的高时间复杂度问题。文章详细解析了算法思路,并提供了具体实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题目给出了n个数字,要求出这个n个数组组成的序列的最长上升子序列(longest increasing subsequence);

首先容易想到的是dp的做法,想到用 dp[i] d p [ i ] 来表示第1-n个数字组成的LIS的长度;

那么可以得到递推式: dp[i]=max(dp[i1],dp[j]+1) d p [ i ] = m a x ( d p [ i − 1 ] , d p [ j ] + 1 ) j是在[1,i]区间中能与a[i]组成LIS的数字;

但是这样每次在求递推式dp[i]的时候都需要去遍历一次区间[1,n],复杂度是O(n^2),会TLE;

dp的做法代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
int a[maxn],dp[maxn];
int n,ans;

int main() {
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    fill(dp, &dp[maxn-1], 1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            if(a[i]>a[j]){
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
    }
    ans=*max_element(dp, &dp[maxn-1]);
    cout<<ans<<endl;
    return 0;
}

然后想到我们可以换一个方法, 假想, 如果在区间[1,i]中有几个数字的LIS长度都是一样的,那么如果希望LIS长度尽量大,我们就应该更愿意选取结尾数字比较小的,这样可以让后面的数字选择更小的就可以满足LIS;

a[i]表示第i个数据。
dp[i]表示表示长度为i+1的LIS结尾元素的最小值。
利用贪心的思想,对于一个上升子序列,显然当前最后一个元素越小,越有利于添加新的元素,这样LIS长度自然更长。
因此,我们只需要维护dp数组,其表示的就是长度为i+1的LIS结尾元素的最小值,保证每一位都是最小值,这样子dp数组的长度就是LIS的长度

最终代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+6;
const int inf=0x7fffffff;
int a[maxn],dp[maxn];
int n,ans;

int main() {
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    fill(dp, dp+n, inf);
    for(int i=0;i<n;i++){
        *lower_bound(dp, dp+n, a[i])=a[i];
    }
    cout<<lower_bound(dp, dp+n, inf)-dp<<endl;
    return 0;
}

错点:
1.填充的时候要填充为inf;
2.在遍历的时候可以直接*lower_bound(dp, dp+n, a[i])=a[i];,这样不论是替换还是补充在序列的最后面都可以实现(其他元素已经初始化为了inf)

# ==================== GCD Routing 脚本 (修改版) ==================== # 设计名称与工艺平台 set DESIGN_NAME "microwatt" set ACTUAL_TOP_MODULE_NAME "microwatt" set PLATFORM "nangate45" # --- 路径配置 --- set PLATFORM_DIR "./platforms/${PLATFORM}" set RESULTS_DIR "./results/${PLATFORM}/${DESIGN_NAME}/routing" set SDC_FILE "./results/${PLATFORM}/${DESIGN_NAME}/cts/4_cts.sdc" file mkdir $RESULTS_DIR # === 技术文件配置 === set TECH_LEF "${PLATFORM_DIR}/lef/NangateOpenCellLibrary.tech.lef" set SC_LEF "${PLATFORM_DIR}/lef/NangateOpenCellLibrary.macro.mod.lef" set LIB_FILES "${PLATFORM_DIR}/lib/NangateOpenCellLibrary_typical.lib" # === 环境变量配置 === set ::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) 4 set ::env(DONT_USE_CELLS) "TAPCELL_* FILLER_*" set ::env(SCRIPTS_DIR) "./scripts" set ::env(REPORTS_DIR) "./reports" set ::env(LIB_FILES) $LIB_FILES set ::env(RESULTS_DIR) $RESULTS_DIR # === 新增拥塞优化参数 === set ::env(MIN_ROUTING_LAYER) metal2 set ::env(MAX_ROUTING_LAYER) metal10 set ::env(FILL_CELLS) "FILLCELL_X1 FILLCELL_X2 FILLCELL_X4 FILLCELL_X8 FILLCELL_X16 FILLCELL_X32" set ::global_route_congestion_report "$::env(REPORTS_DIR)/congestion.rpt" set ::env(ROUTING_LAYER_ADJUSTMENT) 0.2 ;# 降低布线层使用率(原0.4) set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10 ;# 增加二极管插入迭代次数 set ::env(GLB_RT_OVERFLOW_ITERS) 100 ;# 增加拥塞优化迭代次数 set ::env(GLB_RT_ADJUSTMENT) 0.3 ;# 增加布线资源调整因子 set ::env(GLB_RT_ALLOW_CONGESTION) 0.1 ;# 允许轻度拥塞 set ::env(GLB_RT_L1_ADJUSTMENT) 0.99 ;# 调整金属层1资源分配 # ==== 读取设计 ==== read_lef $TECH_LEF read_lef $SC_LEF read_liberty $LIB_FILES read_db "./results/${PLATFORM}/${DESIGN_NAME}/cts/4_1_cts.odb" read_sdc $SDC_FILE # 加载平台RC配置文件 source ${PLATFORM_DIR}/setRC.tcl source $::env(SCRIPTS_DIR)/util.tcl # ==== 全局布线优化 ==== puts "=== 开始增强型全局布线 ===" # 执行引脚布线访问 pin_access -bottom_routing_layer $::env(MIN_ROUTING_LAYER) \ -top_routing_layer $::env(MAX_ROUTING_LAYER) # 执行全局布线(增加拥塞优化迭代) global_route -congestion_iterations 50 \ -congestion_report_file $::global_route_congestion_report \ -verbose 2 set_placement_padding -global \ -left $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) \ -right $::env(CELL_PAD_IN_SITES_DETAIL_PLACEMENT) # 设置传播时钟 set_propagated_clock [all_clocks] estimate_parasitics -global_routing set_dont_use $::env(DONT_USE_CELLS) # 天线效应预检查 check_antennas -report_file $::env(REPORTS_DIR)/antenna_pre.rpt # Repair design using global route parasitics repair_design_helper # Running DPL to fix overlapped instances global_route -start_incremental detailed_placement global_route -end_incremental \ -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_design.rpt # Repair timing using global route parasitics puts "Repair setup and hold violations..." estimate_parasitics -global_routing repair_timing_helper # Running DPL to fix overlapped instances global_route -start_incremental detailed_placement global_route -end_incremental \ -congestion_report_file $::env(REPORTS_DIR)/congestion_post_repair_timing.rpt # 保存全局布线结果 write_def $ RESULTS_DIR/5_1_grt.def write_db $ RESULTS_DIR/5_1_grt.odb # ==== 详细布线优化 ==== puts "=== 开始详细布线(含拥塞优化)===" # 配置高级布线参数 set detailed_route_args " -output_drc $::env(REPORTS_DIR)/route_drc.rpt -output_maze $::env(REPORTS_DIR)/maze.log -drc_report_iter_step 10 -verbose 3 -bottom_routing_layer $::env(MIN_ROUTING_LAYER) -top_routing_layer $::env(MAX_ROUTING_LAYER) -distributed -num_cpus 4 " # 迭代式布线修复(3次迭代) for {set i 0} {$ i < 3} {incr i} { detailed_route {*}$detailed_route_args repair_antennas -iterations 5 } # 保存详细布线结果 write_def $RESULTS_DIR/5_2_route.def write_db $RESULTS_DIR/5_2_route.odb # ==== 填充单元插入 ==== puts "=== 开始填充单元插入 === " filler_placement $::env(FILL_CELLS) write_def $ RESULTS_DIR/5_3_fillcell.def write_db $ RESULTS_DIR/5_3_fillcell.odb # 最终设计检查 check_antennas -report_file $::env(REPORTS_DIR)/antenna_final.rpt report_design_area -file $::env(REPORTS_DIR)/area_final.rpt puts "Routing阶段完成!优化后拥塞率降低至可接受范围" 检查脚本语句语法是否错误
最新发布
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值