zoukankan      html  css  js  c++  java
  • Codeforces713C Sonya and Problem Wihtout a Legend(DP)

    题目

    Source

    http://codeforces.com/problemset/problem/713/C

    Description

    Sonya was unable to think of a story for this problem, so here comes the formal description.

    You are given the array containing n positive integers. At one turn you can pick any element and increase or decrease it by 1. The goal is the make the array strictly increasing by making the minimum possible number of operations. You are allowed to change elements in any way, they can become negative or equal to 0.

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 3000) — the length of the array.

    Next line contains n integer ai (1 ≤ ai ≤ 109).

    Output

    Print the minimum number of operation required to make the array strictly increasing.

    Sample Input

    7
    2 1 5 11 5 9 11
    5
    5 4 3 2 1

    Sample Output

    9
    12

    分析

    题目打给说给一个序列,可以进行若干次操作,每次操作选择一个数让它+1或-1,问最少要几次操作使得序列变为严格单调递增序列。

    首先考虑不是严格递减的情况,这其实是个经典问题的样子,太弱都没做过。。

    • 不严格递减最后修改完成后的各个数一定是原序列中的某一个数

    这个大概可以这么理解:原序列,从左到右扫过去,如果左边的大于右边的,要嘛左边的减掉使其等于右边的,要嘛右边的加上使其等于左边的。


    于是就可以考虑用dp来做了:

    • dp[i][j]表示序列前i个数都单调递增且第i个数更改为不大于原序列中第j个数的最少代价
    • 转移就是dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(a[i],b[j])),a是原序列,b是原序列排序去重的序列

    回到原问题,原问题是求严格单调递增,这个可以转化成不严格单调递增:

    • 让原序列每个数a[i]减去i

    这样转化可行是因为:

    这个转化感觉挺神奇的。。

    代码

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    long long d[3333][3333],a[3333],b[3333];
    int main(){
    	int n;
    	scanf("%d",&n);
    	for(int i=1; i<=n; ++i){
    		scanf("%d",a+i);
    		a[i]-=i;
    		b[i]=a[i];
    	}
    	sort(b+1,b+1+n);
    	int bn=unique(b+1,b+1+n)-b-1;
    	memset(d,127,sizeof(d));
    	for(int i=1; i<=bn; ++i){
    		d[1][i]=min(d[1][i-1],abs(a[1]-b[i]));
    	}
    	for(int i=2; i<=n; ++i){
    		for(int j=1; j<=bn; ++j){
    			d[i][j]=min(d[i][j-1],d[i-1][j]+abs(a[i]-b[j]));
    		}
    	}
    	printf("%lld",d[n][bn]);
    	return 0;
    }
    
  • 相关阅读:
    WinCE 手机互联
    Android 之 getSharedPreferences 和 getPreferences
    Android 之 ListView 点击响应代码?
    Android 之 selector
    昨天晚上被 Android 手机上的广告程序折磨了
    今天终于将第一个 Android NDK 程序编译、运行成功
    Android 4.0.1 源代码编译
    The connection to adb is down, and a severe error has occured.
    成绩转换
    兄弟郊游问题
  • 原文地址:https://www.cnblogs.com/WABoss/p/5876968.html
Copyright © 2011-2022 走看看