cf 1437C. Chef Monocarp(DP,背包)

题目链接:https://codeforces.ml/contest/1437/problem/C

题意:T组样例

每组一个n,然后大小为n的数组a(1<=ai<=n)。然后要求取n个不一样的数bi且>0,然后计算sum(abs(ai-bi))的最小值。

题解:

很像是背包对不对,背包是怎样的,容量为n,然后dp[i]表示容量为i的时候的最大值。这题,可以转化为背包,不过dpi表示最小值。

//emmmm还是不擅长转化问题呀,简单题做多了emmm

代码:

#include <bits/stdc++.h>

#define ll long long
#define pi acos(-1)
#define pb push_back
#define mst(a, i) memset(a, i, sizeof(a))
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define dbg(x) cout << #x << "===" << x << endl
using namespace std;
template <class T> void read(T &x) {
    T res = 0, f = 1;
    char c = getchar();
    while (!isdigit(c)) {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (isdigit(c)) {
        res = (res << 3) + (res << 1) + c - '0';
        c = getchar();
    }
    x = res * f;
}
void print(ll x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) print(x / 10);
    putchar(x % 10 + '0');
}
const ll maxn = 4e2 + 10;
const ll mod = 80112002;

ll n,a[maxn],vis[maxn];
ll dp[maxn];
// ll gcd(ll a,ll b){return (b==0)?a:gcd(b,a%b);}
// ll qpow(ll a,ll p,ll mod){ll
// ans=1;a=a%mod;while(p){if(p&1)ans=(ans*a)%mod;p>>=1;a=(a*a)%mod;}return ans;}
int main() {
    ll _s = 1;
    read(_s);
    for (ll _ = 1; _ <= _s; _++) {
        read(n);
        mst(vis,0);
        for(ll i=1;i<=n;i++) read(a[i]);
        sort(a+1,a+1+n);
		mst(dp,0x3f3f3f3f);
		dp[0]=0;
        for(ll i=1;i<=2*n;i++){
            for(ll j=n;j>=1;j--){
				dp[j]=min(dp[j],dp[j-1]+abs(a[j]-i));
			}
        }
        cout<<dp[n]<<endl;
    }
    return 0;
}
/*
input:::
output:::
*/

再附上一段代码,之前看的别人的代码emmm。

dp[i][j]表示最大值i时取j个时的最小花费。转移是dp[i][j]->dp[i+1][j],dp[i][j]->dp[i+1][j+1]。。。dp,关注怎么转移的!!!(而且转移的上一步应该已经是最优子结构了)然后再直接上代码。

        for(ll i=0;i<=2*n;i++) for(ll j=0;j<=n;j++) dp[i][j]=1e10;
        dp[0][0]=0;        
        for(ll i=0;i<=2*n;i++){
            for(ll j=0;j<=n;j++){
                if(dp[i][j]<1e10){
                    dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
                    dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]+abs(a[j+1]-(i+1)));
                }
            }
        }
        mi=1e10;
        for(ll i=0;i<=2*n;i++) mi=min(mi,dp[i][n]);

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值