4
3 4 2 2
4
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.
这次比赛刚开始感觉还不错,一直都是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; }
ZZUOJ - 10377 - squee_spoon and his Cube III (DP)
原文地址:http://blog.csdn.net/u014355480/article/details/45032041