• dp不平衡数组


    链接:https://ac.nowcoder.com/acm/contest/5881/C
    来源:牛客网

    不平衡数组
    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    给定一个长度为 n 的数组。要求相临的数大小不相同,假如相临数的相同,
    你可以通过将 a[i]+1 来改变它的大小,但是需要付出 b[i]的代价,同时对于每
    个 a[i]只能加一次。问你付出的最小代价。

    输入描述:

    第 1 行 1 个整数 n,表示数组长度为 n
    接下来 n 行,每行 2 个正整数 a[i]与 b[i],表示 a 数组中的第 i 个数,以及将第 i 个数+1 的代价。
    对于20%的数据,保证b[i] = 1
    对于另外10%的数据,保证所有a[i]相等
    对于另外10%的数据,保证所有的a[i]不相等
    对于100%的数据,1<=n<=2e5,0<=a[i]、b[i]<=1e9

    输出描述:

    1 行,一个数字 ans,表示最小代价。
    示例1

    输入

    复制
    4
    1 2
    2 2
    2 3
    4 1

    输出

    复制
    2
    因为每一位只能加一次,所以比较容易想到dp,用dp[i][0]表示当前位置不加一,dp[i][1]表示当前位置加一,那么我们每次只要关心前后两位在加一或不加的状态下会不会冲突就行了,
    不冲突我们就能递推了,具体转移方程如下:


    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    //f[i][1]代表加
    //f[i][0]代表不加 
    ll a[maxn],b[maxn],f[maxn][2];
    int main(){
        int n,m;
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i],&b[i]);
        }
        f[1][1]=b[1];
        for(int i=2;i<=n;i++){
            if(a[i]==a[i-1]){
                f[i][1]=f[i-1][0]+b[i];
                f[i][0]=f[i-1][1];
            }
            else{
                if(a[i-1]+1==a[i]){
                    f[i][1]=min(f[i-1][1],f[i-1][0])+b[i];
                    f[i][0]=f[i-1][0];
                }
                else if(a[i-1]==a[i]+1){
                    f[i][0]=min(f[i-1][0],f[i-1][1]);
                    f[i][1]=f[i-1][1]+b[i];
                }
                else{
                    f[i][0]=min(f[i-1][1],f[i-1][0]);
                    f[i][1]=min(f[i-1][1],f[i-1][0])+b[i];
                }
            }
        }
        ll ans=min(f[n][0],f[n][1]);
        printf("%d",ans);
        
    }
    n = read();
      for(int i = 1 ; i <= n ; ++i){
        a[i] = read(),b[i] = read();
        dp[i][0] = dp[i][1] = INF;
      }
      dp[1][0] = 0; dp[1][1] = b[1];
      for(int i = 2; i <= n ; ++i) {
        if (a[i] != a[i - 1]) dp[i][0] = min(dp[i][0], dp[i - 1][0]);
        if (a[i] != (a[i - 1] + 1)) dp[i][0] = min(dp[i][0], dp[i - 1][1]);
        if ((a[i] + 1) != a[i - 1]) dp[i][1] = min(dp[i][1], dp[i - 1][0] + b[i]);
        if ((a[i] + 1) != (a[i - 1] + 1)) dp[i][1] = min(dp[i][1], dp[i - 1][1] + b[i]);
      }
      ll ans = min(dp[n][0],dp[n][1]);
  • 相关阅读:
    给定一个整数数组和一个目标值,找出数组中和为目标值的两个数 例如给定nums = [2,7,11,15],target = 9
    python的基本语法
    POSIX标准 库文件
    C 标准库头文件
    管理工具:SWOT、PDCA、6W2H、SMART、WBS、时间管理
    函数指针和指针函数的区别
    Linux之正则表达式1
    windows与linux换行规则
    Linux之find
    Linux之文件(目录)默认权限、特殊权限与隐藏权限
  • 原文地址:https://www.cnblogs.com/lipu123/p/13052630.html
Copyright © 2020-2023  润新知