hdu3280Equal Sum Partitions (区间DP)

Problem Description

An equal sum partition of a sequence of numbers is a grouping of the numbers (in the same order as the original sequence) in such a way that each group has the same sum. For example, the sequence:

2 5 1 3 3 7

may be grouped as:

(2 5) (1 3 3) (7)

to yield an equal sum of 7.

Note: The partition that puts all the numbers in a single group is an equal sum partition with the sum equal to the sum of all the numbers in the sequence.

For this problem, you will write a program that takes as input a sequence of positive integers and returns the smallest sum for an equal sum partition of the sequence.

Input

The first line of input contains a single integer
P
, (1 ≤ P ≤ 1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by a decimal integer
M, (1 ≤ M ≤ 10000), giving the total number of integers in the sequence. The remaining line(s) in the dataset consist of the values, 10 per line, separated by a single space. The last line in the dataset may contain less than
10 values.

Output

For each data set, generate one line of output with the following values: The data set number as a decimal integer, a space, and the smallest sum for an equal sum partition of the sequence.

Sample Input

3
1 6
2 5 1 3 3 7
2 6
1 2 3 4 5 6
3 20
1 1 2 1 1 2 1 1 2 1
1 2 1 1 2 1 1 2 1 1

Sample Output

1 7
2 21
3 2

题意:给出一个序列,假设能把该序列分成若干段,使每段和相等,求最小和,若不能分则和为这一整序列。
#include<stdio.h>
int dp[7000][7000];
int min(int a,int b)
{
    return a>b?b:a;
}
int main()
{
    int a[10005],ans[10005],t,c,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&c,&m); ans[0]=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&a[i]);
            ans[i]=ans[i-1]+a[i];
        }
        for(int r=0;r<m;r++)
        for(int i=1;i<=m-r;i++)
        {
            int j=i+r;
            dp[i][j]=ans[j]-ans[i-1];
            for(int k=i;k<j;k++)
            {
                if(ans[k]-ans[i-1]==dp[k+1][j])
                dp[i][j]=min(dp[i][j],dp[k+1][j]);
                if(dp[i][k]==ans[j]-ans[k])
                dp[i][j]=min(dp[i][j],dp[i][k]);
                if(dp[i][k]==dp[k+1][j])
                dp[i][j]=min(dp[i][j],dp[i][k]);
            }
        }
        printf("%d %d\n",c,dp[1][m]);
    }
}
时间: 2024-11-11 15:18:08

hdu3280Equal Sum Partitions (区间DP)的相关文章

uva10891 Game of Sum 博弈区间dp

// uva10891 Game of Sum // 这是在训练指南上看到的一题,啃了很久很久,到现在有 // 一定的动态规划的基础,然而博弈性的东西依然不会 // // // 一开始想的是dp(i,j)表示在i,j段取得最大值 // dp(i,j) = max(dp(i,i),d(i.i+1),...d(i,j-1),d(j-1,j),d(j-2,j)...d(i+1)(j);,sum(i,j)) // 然而,连样例都没过... // // 把表打出来看了一下,发现只是每次取了当前的最大值,根

UVA - 10891 Game of Sum (区间dp)

题意:AB两人分别拿一列n个数字,只能从左端或右端拿,不能同时从两端拿,可拿一个或多个,问在两人尽可能多拿的情况下,A最多比B多拿多少. 分析: 1.枚举先手拿的分界线,要么从左端拿,要么从右端拿,比较得最优解. 2.dp(i, j)---在区间(i, j)中A最多比B多拿多少. 3.tmp -= dfs(i + 1, r);//A拿了区间(l, i),B在剩下区间里尽可能拿最优 tmp是A拿的,dfs(i + 1, r)是B比A多拿的,假设dfs(i + 1, r)=y-x,y是B拿的,x是A

UVA 10891 Game of Sum(区间DP(记忆化搜索))

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1832 题目大意: 两个人在玩一个游戏: 给你一行n个数字,每次只能从左端或者右端取一个或多个数字. 每个人的分值就是他们各自取得的数字之和. 假设两人都足够聪明,问先手最多能比后手多多少分. 解题思路: 其实题目意思就是先手最多能得到多少分. 设dp[l][r]是取完[l,r]的

UVA 10891 Game of Sum 区间dp

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 题目意思大致是给你一串数字,A,B两个人轮流从两端取一段数字并得到该串数字的和的点数,每个人都尽可能的多的点数,问A最多能比B多多少点. 区间dp,一开始打算分AB,但是发现太麻烦了,最后用dp(l,r)表示在区间l~r中先手能赢的的最多点数.假设A是区间(l,r)的先手的话,如果A选择了(l,k )// 或(k+1,r)的数字,那他的得分(l,r)的总分减去B在余

UVA10891 Game of Sum 区间DP

好像带点博弈,又好像没有. 设dp[i][j] 为[i,j]区间内先手得分的最大值(这里的先手不一定是指player A!) 这时候只需要枚举出现在的先手会取哪一边,取几个,然后现在的最优状态就可以由以前的状态推出来 那么dp[i][j] = sum[i,j]-min(dp[i+1][j],dp[i+2][j],....,dp[j][j],dp[i][j-1],...,dp[i][i],0); 举个例子: 例如说sum[i,j]-dp[i+1][j]是指先手取了[i,j]的第一个元素即 A[i]

Uva 10891 Game of Sum(区间博弈dp)

10891 - Game of Sum Time limit: 3.000 seconds This is a two player game. Initially there are n integer numbers in an array and players A and B get chance to take them alternatively. Each player can take one or more numbers from the left or right end

区间dp专题练习

区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西,\(n^2\)自己写去 \[\ \] \[\ \] 2.You Are the One 感觉自己智力被吊打 \(dp[i][j]\)表示 , 对于当前的一个空栈 , \(i\)到\(j\)这一段都出栈的最小花费 显然是长得一副区间(诡)dp(异)的样子 , 如何转移呢?(建议自己想想吧) 对于一个\(dp[i][j]\),因为这个\(i\)必须是最先入栈的 , 所以我们可以枚举它的出栈时间\(k\) , 那么总贡

合并石子 区间dp水题

合并石子 链接: nyoj 737 描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆.合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆.求出总的代价最小值. tags:最基本的区间dp,这题范围小,如果n大一些,还是要加个平行四边行优化. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring&g

Luogu P2734 游戏 A Game 区间DP

P2734 游戏 A Game 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该数字被去掉并累加到本玩家的得分中,当数取尽时,游戏结束.以最终得分多者为胜. 题目描述 编一个执行最优策略的程序,最优策略就是使玩家在与最好的对手对弈时,能得到的在当前情况下最大的可能的总分的策略.你的程序要始终为第二位玩家执行最优策略. 输入输出格式 输入格式: 第一行: 正整数N, 表示序列中正整数的个数