codeforces gym101482 C Cent Savings dp

https://vjudge.net/problem/Gym-101482C
在這裏插入圖片描述
題目大意:按順序給出nn個物品,你可以把他們分組,最多分成d+1d+1組,每組內的價值按照四捨五入計算,問最少可以付多少錢。

思路:dp[i][j]dp[i][j]表示從ii開始分jj個組最少需要付多少錢。設sumisum_i表示前綴和,get(sumi)get(sum_i)表示四捨五入後的值,那麼有:dp[i][k]=min(dp[j][k1]+get(sumj1sumi1))dp[i][k]=min(dp[j][k-1]+get(sum_{j-1}-sum_{i-1}))其中i<j<=ni<j<=n,逆序dpdp就好了,複雜度O(n2d)O(n^2*d)

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define pr pair<int,int>
using namespace std;
typedef long long ll;

int n,m;
int a[2005],sum[2005];
int dp[2005][25];

int getval(int x)
{
    if(x%10>=5)
        x=(x/10+1)*10;
    else
        x=x/10*10;
    return x;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    memset(dp,INF,sizeof(dp));
    for(int i=n;i>=1;i--)
        dp[i][1]=getval(sum[n]-sum[i-1]);
    for(int i=n;i>=1;i--)
    {
        for(int k=2;k<=m+1;k++)
        {
            for(int j=i+1;j<=n;j++)
                dp[i][k]=min(dp[i][k],dp[j][k-1]+getval(sum[j-1]-sum[i-1]));
        }
    }
    int ans=INF;
    for(int i=1;i<=m+1;i++)
        ans=min(ans,dp[1][i]);
    printf("%d\n",ans);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章