codeforces 590D

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 k leftmost 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 s swaps of two consecutive soldiers.

Input

The first line of the input contains three positive integers nks (1 ≤ k ≤ n ≤ 150, 1 ≤ 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.

题目大意:

N个数,最多S次交换次数,每次能交换相邻两个数,问前k个数的最小总和是多少。

输入:

样例1

3 2 2
2 4 1

样例2
5 4 2
10 1 6 2 5

样例3

5 2 3
3 1 4 2 5

输出:

样例1

3

样例2

18

样例3

3

思路:dp

dp[i][j][k]表示前i个数放入j个,交换了k次(转移表达式挺巧妙的

当前i不选则有,dp[i][j][k] = dp[i-1][j][k]

若选dp[i][j][k] = min( dp[i][j][k] , dp[i-1][j-1][k-(i-j)] ) (第i个选,单i的交换次数为k-(i-j),实际上就是i距离当前长度j序列的距离

再用滚动数组优化一下就好了~

(有看到开二维数组dp的解法,不过不是很理解为了避免后效性,外层从大到小枚举,内层从小到大枚举

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define int long long
using namespace std;

typedef long long ll;

const int N = 1e9+10;
int  dp[2][160][160*160];//dp[i][j][k]表示考虑前i个数放入j个交换了k次的最小值
int a[160];
signed  main()
{
    IOS;
    mst(dp,INF);
    int n,k,s;
    cin>>n>>k>>s;
    _for(i,1,n) cin>>a[i];
    dp[0][0][0] = 0;
    dp[1][0][0] = 0;
    _for(i,1,n)
    {
        int p = i & 1;
        int q =  1^p;
        mst(dp[i&1][0],0);
        _for(j,1,i)
        {

            _for(k,0,i*j)
            {
                dp[p][j][k] = dp[q][j][k];
                if( k >= i-j )
                dp[p][j][k] = min( dp[p][j][k] , a[i] + dp[q][j-1][k-(i-j)]);
            }
        }
    }
    ll ans = INF;
    _for( i,0,min(s,n*(n-1)/2) )
    ans = min(ans,1ll * dp[n&1][k][i]);

    cout<<ans<<endl;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值