zzuoj 10377: squee_spoon and his Cube III (DP状态转移)

来源:互联网 发布:网狐6603棋牌源码下载 编辑:程序博客网 时间:2024/06/12 23:51

                                                                        10377: squee_spoon and his Cube III

                                                                                                Time Limit:2 Sec Memory Limit: 128 MB

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, theithcompetitor’s past result isai 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 ofn 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 ithcompetitor’s result.

Output

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

Sample Input

43 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.

//偶然看到这篇博客,发现题很不错,就想着写一下,但却没啥思路,还是看大神的思路吧。。(没找到ZZuoj,所以也就没提交。。)

首先说下题意。就是一个比赛(安排得很紧凑),最多3个人同时比,每个人需要的时间是已知的,问最少总共花多少时间。或者可以想象成这样:三张桌子,一个选手比完下一个上。

        问题就可以转化为:有一些数,分为三组,需要使得和最大的那组尽可能小。

        这个问题可以通过dp(动态规划)来解决。dp(i,j)的第一维表示第一组的总时间,第二维表示第二组的总时间,第三组的总时间自然就是所有选手的时间之和减去前两组的时间。

        首先初态是dp[0][0]=true。此时三组为空,安排每个选手上台比赛,尝试把当前的选手的时间a加入每个组。如果加入第一组,就加在第一维上;如果加入第二组,就加在第二维上;如果加入第三组,不需要操作。即:

if(dp[i][j]==true){

dp[i+a][j]=true;

dp[i][j+a]=true;

}

        处理完所有选手后,我们就可以通过考察所有为true的dp[i][j],来找最小可能时间了。

        但是,如果仅仅做到这一步,还是会超时。需要进行一些优化。考虑三组的时间是可以互换的,设总时间为tot,我们可以让前两组的时间<=tot/3+60。

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;int dp[1010][1010];int a[60];int main(){int n,i,j,k;int sum;while(scanf("%d",&n)!=EOF){sum=0;for(i=0;i<n;i++){scanf("%d",&a[i]);sum+=a[i];}int ans=sum/3+60;memset(dp,0,sizeof(dp));dp[0][0]=1;for(k=0;k<n;k++){for(i=ans;i>=0;i--){for(j=ans;j>=0;j--){if(dp[i][j]){dp[i+a[k]][j]=1;dp[i][j+a[k]]=1;}}}}int kk=sum;for(i=0;i<kk;i++){for(j=0;j<kk;j++){if(dp[i][j]){int tmp=max(i,j);tmp=max(tmp,sum-i-j);kk=min(kk,tmp);}}}printf("%d\n",kk);}return 0;}


 

0 0