ZZUOJ - 10377 - squee_spoon and his Cube III (DP)

10377: squee_spoon and his Cube III

Time Limit: 2 Sec  Memory Limit: 128 MB

Submit: 70  Solved: 22

[Submit][Status][Web
Board
]

Description

As we all know, pupil squee_spoon plays Rubik‘s Cube every day. He registered a Cube competition recently. Many competitors will attend this competition. But limited by the area,at most 3 competitors
can compete at the same time
, proper arrangement will save time.

There are n competitors registered the competition, we can look up every person’s competition history by visiting World Cube Association (WCA) official website, the ithcompetitor’s past result is ai second(s). To simplify
the problem, we assume every competitor will get the same result as he/she did in past competition. For example, squee_spoonfinished his solving in last competition with the result of 8 seconds, so we think that he will
also get 8 seconds in the upcoming competition.

To become a international grandmaster, you must solve this problem. Schedule all of n competitors, and make the total time as short as possible.

Input

Single test case.

The first line contains an integer n (1<=n<=50) -- the number of competitors.

The second line contains n integers a1~an (1<=ai<=60), ai indicate the ith competitor’s result.

Output

Print a single number, the minimum total time of this competition.

Sample Input

4
3 4 2 2

Sample Output

4

HINT

In the sample, we can divide all competitors into 3 groups:(1)(2)(3,4)

- At the beginning, 1st, 2nd and 3rd competitor started.

- At the end of 2 second, 3rd competitor finished. 4th competitor started.

- At the end of 3 second, 1st competitor finished.

- At the end of 4 second, 2nd and 4th competitor finished. All 4 persons has finished.

So the minimum total time is 4 seconds.

Source

[Submit][Status][Web
Board
]

这次比赛刚开始感觉还不错,一直都是1A,除了第一次CE╮(╯▽╰)╭,水题还是比较熟练地,然后出了5个后就歇菜了,一直卡在那个行列式的那个水题之上,其实一开始的做法是对的,但是忘记了特判等于1的情况,然后又用DFS各种做,然后TLE,然后就没然后啦,,赛后交下第一次加个特判的代码就过啦,不甘心啊。。。。而且那个表达式求值的题目也是基础题,但是还是敲挫了好多次,,,╮(╯▽╰)╭,,,代码能力啊!!!

然后这题,,袁学长出的废题,就是DP啦,一直找不到状态以及方程,然后贪心一下交了,果然WA

这里将dp[i][j]看做第一组有i个和第二组有j个的情况(第三组可以通过前两组以及总数得出)是否存在,存在的话就赋值为1,整个dp是用来表示所有可能的情况,最后再扫一遍找最小值

总结:找出状态解一切(dp题比较难想,但是很多时候看下题解又感觉很容易)

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int n;
bool dp[1500][1500];
int a[55];

int main() {
	while(scanf("%d", &n) != EOF) {
		memset(dp, 0, sizeof(dp));

		int tot = 0;
		for(int i = 0; i < n; i++) {
			scanf("%d", &a[i]);
			tot += a[i];
		}

		int end = tot / 3 + 55;
		dp[0][0] = 1;
		for(int k = 0; k < n; k++) {
			for(int i = end; i >= 0; i--) {
				for(int j = end; j >= 0; j--) {
					if(dp[i][j]) {
						dp[i + a[k]][j] = 1;
						dp[i][j + a[k]] = 1;
					}
				}
			}
		}

		int ans = tot;
		for(int i = 0; i <= end; i++) {
			for(int j = 0; j <= end; j++) {
				if(dp[i][j]) {
					int tmp = max(i, j);
					tmp = max(tmp, tot - i - j);
					ans = min(tmp, ans);
				}
			}
		}

		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-10-11 14:56:24

ZZUOJ - 10377 - squee_spoon and his Cube III (DP)的相关文章

[LightOJ1017]Brush (III)(dp)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1017 题意:给你一个无限大的平面(2D)上面有N个 点,一个宽w的刷子,最多使用k次,每次使用只能横着水平刷一次.问刷k次后刷过的地方最多可以覆盖多少个点. 思路:其实读完题就知道这个题和x坐标没关系,我们只需要关心每一个点的y坐标就行了.可以动态规划,输入完后给每一个点的y坐标从小到大排序,定义dp(i,k)为前i个点刷了k次后最大能刷到的点数.转移的时候有两种情况,一种是之前刷了

hdu 2122 Ice_cream’s world III(最小生成树)

感觉就是 畅通工程的改版 直接贴代码了 #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define ll __int64 #define MA

POJ 1988 Cube Stacking(转)

这道题的思路,就是每次记下该点到父结点的个数,并记录下其下的结点个数.之后,每次"C"时,将总的减去它所压的方块,即答案!!!(也是参考别人的~-?) <pre name="code" class="cpp">#include<stdio.h> #include<iostream> using namespace std; #define max 30010 struct node { int parent;/

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

HDU 4908 (杭电 BC #3 1002题)BestCoder Sequence(DP)

题目地址:HDU 4908 这个题是从m开始,分别往前DP和往后DP,如果比m大,就比前面+1,反之-1.这样的话,为0的点就可以与m这个数匹配成一个子串,然后左边和右边的相反数的也可以互相匹配成一个子串,然后互相的乘积最后再加上就行了.因为加入最终两边的互相匹配了,那就说明左右两边一定是偶数个,加上m就一定是奇数个,这奇数个的问题就不用担心了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h&g

Sicily 1146:Lenny&#39;s Lucky Lotto(dp)

题意:给出N,M,问有多少个长度为N的整数序列,满足所有数都在[1,M]内,并且每一个数至少是前一个数的两倍.例如给出N=4, M=10, 则有4个长度为4的整数序列满足条件: [1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 4, 10], [1, 2, 5, 10] 分析:可用动态规划解题,假设dp[i][j],代表满足以整数i为尾数,长度为j的序列的个数(其中每一个数至少是前一个数的两倍).那么对于整数i,dp[i][j] 等于所有dp[k][j-1]的和,其中k满足:

UVA542 - France &#39;98(dp)

UVA542 - France '98(dp) 题目链接 题目大意:之前题目意思还以为看懂了,其实没看明白,它已经把各个选手分在各自所在的区域里面,这就意味着第一次的PK的分组已经确定,而且冠军必须是从两个左右分区出来的胜利者才有机会pk冠军. 解题思路:那么从1-16这个大的区间内诞生出来的冠军可能是来自左边,也可能是右边,然后再左边右边的子区间递归找出冠军.f[i][l][r]表示l-r这个区间的胜利者是i的概率,那么假设i在区间的最左边,f[i][l][r] = Sum(f[i][l][m

HDU 4968 Improving the GPA(dp)

HDU 4968 Improving the GPA 题目链接 dp,最大最小分别dp一次,dp[i][j]表示第i个人,还有j分的情况,分数可以减掉60最为状态 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, avg, n; double dp1[15][405], dp2[15][405]; double get(int x) { if