递推,动态规划(DP),字符串处理,最佳加法表达式

看了一些资料,竟然发现连百度文库也有错误的地方,在这里吐槽一下
题目大意:http://wenku.baidu.com/link?url=DrUNNm19IqpPNZjKPX4Jg6shJiK_Nho6dPf8I0b5unSmQM6Ji7tNTKU1LFWDyiCoJaMj8hHb_AakLqFZFuz0vxwWHiSdTLqn10FsO2tZx6W
上面还有我的评论哦。

解题报告:
1、对于每一节字符串表示的数,用二维数组sum[i][j]记录
2、状态转移方程
f[i][j]=min(f[i-k][j-1]+num[i-k+1][j]);
3、也是吐槽百度文库的地方,一定记得-‘0‘;

#include <stdio.h>
#include <string.h>
#define MAX 105
#define INF 0x3f3f3f3f

void DP(char *a,int t,int m)//t为加号个数,m为字符串长度
{
    int i,j,d,k,min;
    int f[m+1][t+1];//f[i][j]表示在前i个字符中插入j个加号所能达到的最小值;
    int num[m+1][m+1];//二维数组来存每一节数字的大小,num[i][j]表示字符串从i到j的大小;
    for(i=0; i<=m; i++)
    {
        for(j=0,d=0; j<=m; j++)
        {
            if(i>j)//不能构成数字
                num[i][j]=INF;
            else
            {
                d=d*10+a[j]-‘0‘;
                num[i][j]=d;
            }
        }
    }
    //状态转移方程
    //f[m][j]=min(f[m-i][j-1]+num[m-i+1][m]),这里枚举i的位置
    for(i=1; i<=m; i++)
    {
        for(j=0; j<=t; j++)
        {
            if(j>=i)
                f[i][j]=INF;
            else if(j==0)
                f[i][j]=num[0][i-1];
            else
            {
                for(min=INF,k=1; k<i; k++) //开始枚举i的位置
                {
                    f[i][j]=f[i-k][j-1]+num[i-k][i-1];
                    if(min>f[i][j])
                        min=f[i][j];
                }
                f[i][j]=min;//存起来
            }
        }
    }
    printf("%d\n",f[m][t]);
}

int main()
{
    int times;
    int len;
    char arr[MAX];
    scanf("%s",arr);
    scanf("%d",&times);
    len=strlen(arr);
    DP(arr,times,len);
    return 0;
}
时间: 2024-08-01 10:45:02

递推,动态规划(DP),字符串处理,最佳加法表达式的相关文章

openjudge1768 最大子矩阵[二维前缀和or递推|DP]

总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2 的最大子矩阵是 9 2-4 1-1 8 这个子矩阵的大小是15. 输入 输入是一个N * N的矩阵.输入的第一行给出N (0 < N <= 100).再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给

2017&quot;百度之星&quot;程序设计大赛 - 复赛1003&amp;&amp;HDU 6146 Pok&#233;mon GO【数学,递推,dp】

Pokémon GO Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 171    Accepted Submission(s): 104 Problem Description 众所周知,度度熊最近沉迷于 Pokémon GO. 今天它决定要抓住所有的精灵球! 为了不让度度熊失望,精灵球已经被事先放置在一个2*N的格子上,每一个格子上都

刷题向》关于一道比较优秀的递推型DP(openjudge9275)(EASY+)

先甩出传送门:http://noi.openjudge.cn/ch0206/9275/ 这道题比较经典, 最好不要看题解!!!!! 当然,如果你执意要看我也没有办法 首先,显然的我们可以用 f [ i ] 和 g [ i ] 来表示在第 i 行是公牛或母牛的情况 那么易得递推式:f [ i ] = f [ i - k - 1 ] + g [ i - k - 1 ] , g [ i ] = g [ i - 1 ] + f [ i - 1 ] 于是通过 f [ n ] + g [ n ] 得到最后答

百练4152:最佳加法表达式(dp+高精度)

描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36 输入有不超过15组数据每组数据两行.第一行是整数m,表示有m个加号要放( 0<=m<=50)第二行是若干个数字.数字总数n不超过50,且 m <= n-1输出对每组数据,输出最小加法表达式的值样例输入 2 123456 1 123456 4 12345 样例输出 102 579 15 提示要用到高精度

4152:最佳加法表达式

题目链接 描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值.例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36 输入 有不超过15组数据 每组数据两行.第一行是整数m,表示有m个加号要放( 0<=m<=50) 第二行是若干个数字.数字总数n不超过50,且 m <= n-1 输出 对每组数据,输出最小加法表达式的值 样例输入 2 123456 1 123456 4 12345 样例输出 102 579

[HDOJ6146] Pok&#233;mon GO(递推,dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6146 一个可行的思路是考虑三个子问题 全部走完2*N个格子的方法总数DP[N] 全部走完2*N个格子并且起点是最左边的两个格子之一的方法总数DP2[N] 全部走完2*N个格子并且起点和终点分别是最左边的两个格子的方法总数DP3[N] 组合2和3的答案就可以得到1 了. (其实是找到了原题2333) 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛

hdu 2041(递推、dp/组合数学```其实就是Fibonacci数```)

最经典的Fibonacci数,上楼梯每次能跨一步或者两步,问有多少中跨法: 对于最后一次跨一步或者两步,走到第 i 阶,其种类总数就是走到 i - 1 的总数 + 走到i - 2 的总数:于是 a [ i ] = a [ i - 1 ] + a [ i - 2 ]:当然,那个时候的我是用```组合数学做的``` 1 #include<stdio.h> 2 long long c(int a,int b) 3 { 4 long long i,sum=1,j; 5 for (i=a,j=1;i&g

UVa 1638 Pole Arrangement (递推或DP)

题意:有高为1,2,3...n的杆子各一根排成一行,从左边能看到L根,从右边能看到R根,求杆子的排列有多少种可能. 析:设d(i, j, k)表示高度为1-i的杆子排成一行,从左边看到j根,从右边看到k根的数目.当i>1时,我们按照从大到小的顺序按排杆子, 假设已经安排完i-1根了,那么还剩下一根就是高度为1的了,那么它放在哪都不会挡住任何一根杆子.情况有3种: 1.放在左边,那么在左边一定能够看到它,在右边看不到(因为i>1): 2.放在右边,那么在右边一定能够看到它,在左边看不到(因为i&

最佳加法表达式

题目描述: 有一个由1..9组成的数字串.问如果将m个加 号插入到这个数字串中,在各种可能形成的 表达式中,值最小的那个表达式的值是多少 (本题只能用于整数) 解题思路: 假定数字串长度是n,添完加号后,表达式的最后一个加号添加在第 i 个数字后面,那么整个表达 式的最小值, 就等于在前 i 个数字中插入 m – 1 个加号所能形成的最小值,加上第 i + 1到第 n 个数字所组成的数的值(i从1开始算). 设dp(m,n)表示在n个数字中插入m个加号所能形成 的表达式最小值,那么: if m