Codeforces Round #327 (Div. 1) D. Top Secret Task(DP)



大致題意:

題意很簡單,就是n個數,求最多兩兩交換S次,使前K個數的和最小

n <= 150, s = 1e9

思路:

顯然s >= n * n / 2 時總能把前K小的數交換到前K個位置

而且交換不交叉時是最優的,比如Ak 與 A(k+x)交換, 接下來Ak-1只能A(k+y)(y > x) 交換,總是最優的

這樣每次交換的代價是j - i,再增加一維可行位置保證不交叉,這樣就是S容量的揹包問題


//package ok;

import java.math.*;
import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.math.BigInteger;  
import java.util.StringTokenizer;  
import java.io.PrintWriter;
import java.util.Arrays;
public class a {

    public static void main(String args[])  {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
            int n = in.nextInt();
            int k = in.nextInt();
            int s = in.nextInt();
            int[] a = new int[n + 100];
            for (int i = 1; i <= n ; i++) a[i] = in.nextInt();
            if(s >= n * (n - 1) / 2) {
                Arrays.sort(a, 1, n + 1);
                int ans = 0;
                for(int i = 1; i <= k; i ++) ans += a[i];
                out.println(ans);
                out.flush();
                return ;
            }
            int [][][]dp = new int[n + 10][s + 10][2];
            int ans = 0;
            for(int i = 1; i <= k; i ++) ans += a[i];
            for(int i = 1; i <= k; i ++) {
                int cur = i & 1;
                for(int j = n; j >= k + 1; j --) 
                    for(int c = 0; c <= s; c ++) {
                        dp[j][c][cur] = Math.max(dp[j+1][c][cur], dp[j][c][cur ^ 1]);
                        if( c >= j - i && a[j] < a[i] ) 
                            dp[j][c][cur] = Math.max(dp[j][c][cur], dp[j + 1][c - (j - i)][cur ^ 1] + a[i] - a[j]);
                    }
            }
            out.println(ans - dp[k + 1][s][k & 1]);
            out.flush();
    }

    static class Scanner {  
        BufferedReader br;  
        StringTokenizer st;  
      
        public Scanner(InputStream in) {  
            br = new BufferedReader(new InputStreamReader(in));  
            eat("");  
        }  
      
        private void eat(String s) {  
            st = new StringTokenizer(s);  
        }  
      
        public String nextLine() {  
            try {  
                return br.readLine();  
            } catch (IOException e) {  
                return null;  
            }  
        }  
      
        public boolean hasNext() {  
            while (!st.hasMoreTokens()) {  
                String s = nextLine();  
                if (s == null)  
                    return false;  
                eat(s);  
            }  
            return true;  
        }  
      
        public String next() {  
            hasNext();  
            return st.nextToken();  
        }  
      
        public int nextInt() {  
            return Integer.parseInt(next());  
        }  
      
        public long nextLong() {  
            return Long.parseLong(next());  
        }  
      
        public double nextDouble() {  
            return Double.parseDouble(next());  
        }  
      
        public BigInteger nextBigInteger() {  
            return new BigInteger(next());  
        }  
      
        public int[] nextIntArray(int n) {  
            int[] is = new int[n];  
            for (int i = 0; i < n; i++) {  
                is[i] = nextInt();  
            }  
            return is;  
        }  
      
        public long[] nextLongArray(int n) {  
            long[] ls = new long[n];  
            for (int i = 0; i < n; i++) {  
                ls[i] = nextLong();  
            }  
            return ls;  
        }  
      
        public double[] nextDoubleArray(int n) {  
            double[] ds = new double[n];  
            for (int i = 0; i < n; i++) {  
                ds[i] = nextDouble();  
            }  
            return ds;  
        }  
      
        public BigInteger[] nextBigIntegerArray(int n) {  
            BigInteger[] bs = new BigInteger[n];  
            for (int i = 0; i < n; i++) {  
                bs[i] = nextBigInteger();  
            }  
            return bs;  
        }  
      
        public int[][] nextIntMatrix(int row, int col) {  
            int[][] mat = new int[row][];  
            for (int i = 0; i < row; i++) {  
                mat[i] = nextIntArray(col);  
            }  
            return mat;  
        }  
      
        public long[][] nextLongMatrix(int row, int col) {  
            long[][] mat = new long[row][];  
            for (int i = 0; i < row; i++) {  
                mat[i] = nextLongArray(col);  
            }  
            return mat;  
        }  
      
        public double[][] nextDoubleMatrix(int row, int col) {  
            double[][] mat = new double[row][];  
            for (int i = 0; i < row; i++) {  
                mat[i] = nextDoubleArray(col);  
            }  
            return mat;  
        }  
      
        public BigInteger[][] nextBigIntegerMatrix(int row, int col) {  
            BigInteger[][] mat = new BigInteger[row][];  
            for (int i = 0; i < row; i++) {  
                mat[i] = nextBigIntegerArray(col);  
            }  
            return mat;  
        }  
    }  
}  




D. Top Secret Task
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A top-secret military base under the command of Colonel Zuev is expecting an inspection from the Ministry of Defence. According to the charter, each top-secret military base must include a top-secret troop that should... well, we cannot tell you exactly what it should do, it is a top secret troop at the end. The problem is that Zuev's base is missing this top-secret troop for some reasons.

The colonel decided to deal with the problem immediately and ordered to line up in a single line all n soldiers of the base entrusted to him. Zuev knows that the loquacity of the i-th soldier from the left is equal to qi. Zuev wants to form the top-secret troop using kleftmost soldiers in the line, thus he wants their total loquacity to be as small as possible (as the troop should remain top-secret). To achieve this, he is going to choose a pair of consecutive soldiers and swap them. He intends to do so no more than s times. Note that any soldier can be a participant of such swaps for any number of times. The problem turned out to be unusual, and colonel Zuev asked you to help.

Determine, what is the minimum total loquacity of the first k soldiers in the line, that can be achieved by performing no more than sswaps of two consecutive soldiers.

Input

The first line of the input contains three positive integers nks (1 ≤ k ≤ n ≤ 1501 ≤ s ≤ 109) — the number of soldiers in the line, the size of the top-secret troop to be formed and the maximum possible number of swap operations of the consecutive pair of soldiers, respectively.

The second line of the input contains n integer qi (1 ≤ qi ≤ 1 000 000) — the values of loquacity of soldiers in order they follow in line from left to right.

Output

Print a single integer — the minimum possible total loquacity of the top-secret troop.

Sample test(s)
input
3 2 2
2 4 1
output
3
input
5 4 2
10 1 6 2 5
output
18
input
5 2 3
3 1 4 2 5
output
3
Note

In the first sample Colonel has to swap second and third soldiers, he doesn't really need the remaining swap. The resulting soldiers order is: (214). Minimum possible summary loquacity of the secret troop is 3. In the second sample Colonel will perform swaps in the following order:

  1. (10, 1, 6 — 2, 5)
  2. (10, 1, 2, 6 — 5)

The resulting soldiers order is (10, 1, 2, 5, 6).

Minimum possible summary loquacity is equal to 18.



發佈了308 篇原創文章 · 獲贊 11 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章