码迷,mamicode.com
首页 > 其他好文 > 详细

B. Snakes

时间:2020-02-23 22:30:15      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:exp   拓展   题目   expand   --   ORC   trick   problem   group   

B. Snakes

https://codeforces.com/group/5yyKg9gx7m/contest/269908/problem/B

题目描述:

St. Patrick要去捕蛇,一开始先拿一个任意size的网去捕蛇,每次捕蛇完剩下的空间为size-蛇的数量。之后拿一个同样size的空网去捕下一个位置的蛇,每次在去下一次捕蛇地点的路上,他可以更换网的size位任意大小。 St. Patrick需要恰好换够k次size。问总共剩余空间最小为多少。

分析:

选定其中一组,假设这个组有k个元素。有m为该组中的最大值。那么这一组的总剩余空间就是k*m-sum(k个元素)。总共有n个地点待分成p组。设dp[ i ] [ j ]中的i表示到第i个地点,j表示已经分成几个组。

dp[ i ] [ j-1 ]+k*m-sum(k个元素)转移到dp[ i ] [ j ]。

k个元素和可通过前缀和实现。

剩余的细节就不清楚了。。。

代码:

#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
typedef long long ll;
const ll INF=9e14;
ll dp[405][405];
int a[405];
int pre[405];
int main()
{
    int n,p;
    cin>>n>>p;
    int mm=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        pre[i]=pre[i-1]+a[i];//前缀和 
    }
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=INF;
    for(int i=1;i<=n;i++)
    {
        mm=max(mm,a[i]);
        dp[i][0]=mm*i-pre[i];//没有分组时的情况
    }
    int m=0;
    for(int j=1;j<=p;j++)//分成p组 
    {   
        for(int i=j+1;i<=n;i++)//每组进行拓展 
        {
            m=a[i];
            for(int k=i-1;k>=j;k--)//逆序时因为(i-k) 
            {
                m=max(m,a[k+1]);//当前组最大的数
                dp[i][j]=min(dp[i][j],dp[k][j-1]+m*(i-k)-(pre[i]-pre[k]));
            }
        }
    }
    printf("%lld\n",dp[n][p]);
    return 0;
}

 

 

B. Snakes

标签:exp   拓展   题目   expand   --   ORC   trick   problem   group   

原文地址:https://www.cnblogs.com/studyshare777/p/12354442.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!