10377: squee_spoon and his Cube III
Time Limit: 2 Sec Memory Limit: 128 MB
Submit: 70 Solved: 22
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
这次比赛刚开始感觉还不错,一直都是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; }