• CodeVS 3415-最小和


    原题

    题目描述 Description

         小浣熊松松来到文具店,选择了K支自己喜欢的水彩笔,并抄下了它们的价格。可是到结算时,他发现自己抄价格时抄得太密集,以至于所有价格连成了一个数字串(你可以假设价格都是正整数)。老板想和松松开个玩笑,于是对他说:“你可以把这个数字串分成K段,代表这K支笔的价格,然后把他们加起来,就是你要付给我的钱了。”当然,松松想尽可能省下钱去买《算法导论》,所以请你来帮忙算算,他最少需要付多少钱。

    输入描述 Input Description

    第一行包含一个整数N,代表松松抄下来的数字串。

    第二行包含一个整数K,代表松松买了K支水彩笔。

    输出描述 Output Description

    输出仅一行,为松松买这些笔最少花的钱。

    样例输入 Sample Input

    79846

    3

    样例输出 Sample Output

    133

    数据范围及提示 Data Size & Hint

    对于20%的数据,K=1;

    对于100%的数据,数字串长度不超过8,K<=数字串长度。

    由于是松松来划分,因此可以出现有前导0的价格,或者价格就是0。

    网址:http://codevs.cn/problem/3415/

    题意

    给一串数字,将它分为K部分,使得这K部分加起来的和最小。

    题解

    这道题数据挺水,dfs和递归貌似也能过,但Code给它的标签是DP,本人也就跟着写了一下DP。

    首先定义一个二维数组F,Fi,j表示数字串前i位分成j部分时的最优解。

    下面给出DP状态转移方程,f[i,j]=min(f[i,j],f[k,j-1]+p(copy(s,k+1,i-k)))

    具体解释:

    定义一个函数p(s),表示将字符串s转为数字(原先读入的为字符串)。

    接下来三重循环:

    for i:=1 to length(s) do//枚举字符串长度

    for j:=1 to min(n,i) do begin//枚举分的份数,但j不能大于i,因为1个数不可能被分成2份

    if j=1 then f[i,j]:=copy(s,1,i) else//如果份数为1则还是它本身

    for k:=1 to i-1 do f[i,j]:=min(f[i,j],f[k,j-1]+p(copy(s,k+1,i-k)));end;//在[1,i)的半开闭区间中不断更新答案找出最优解

    OK下面pia代码:

     1 uses math;
     2 var f:array[0..10,0..10] of int64;
     3 var n,l,i,j,k:longint;
     4 var s:string;
     5 function p(s:string):longint;
     6 var num,i:longint;
     7 begin
     8   num:=0;
     9   for i:=1 to length(s) do num:=num*10+ord(s[i])-48;
    10   exit(num);
    11 end;
    12 begin
    13   readln(s);readln(n);
    14   l:=length(s);
    15   for i:=1 to l do for j:=1 to n do f[i,j]:=maxlongint;
    16   for i:=1 to l do
    17   for j:=1 to min(i,n) do
    18   begin
    19     if j=1 then f[i,j]:=p(copy(s,1,i)) else
    20     for k:=1 to i-1 do f[i,j]:=min(f[i,j],f[k,j-1]+p(copy(s,k+1,i-k)));
    21   end;
    22   writeln(f[l,n]);
    23 end.
    View Code

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    C# checklistbox控件用法总结(怎样得到多选的值,以及动态加载数据)
    Tomcat service.xml详解
    修改windows服务器上面tomcat启动窗口的名称
    表空间
    安装selenium遇到的问题
    oracel 锁表查询
    Can not perform this action after onSaveInstanceState
    Caused by: java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.HEADSET_PLUG
    Java.lang.IllegalStateException Activity has been destroyed
    StrictMode 使用
  • 原文地址:https://www.cnblogs.com/HAdolf-HQY/p/6289509.html
Copyright © 2020-2023  润新知