POJ 2573

还有一道比这道题更简单但是一样的题,忘了题号了,那题只求最少时间,实际上两题差不多,贪心策略

1、让划船划的最快的人依次与最慢的两人组队去对面,然后他在把船划回来,这样到对岸的时间花费很多,但是回来的时间少。

2、先让最快的两人去对岸,然后让其中一人把船划回来,再让最慢的两人组队去对岸,让先前还剩下那人把船划回来,这样使得到对岸的时间减少了,但是划回来的时间增多了。

依靠上面两个贪心策略,执行一次后得到的状态都是相等的,于是可以递归解决,每次进行比较,看哪种贪心策略更优,直到要过河的人小于4

#include<cstdio>

#include<cstring>

#include<algorithm>

using namespace std;

int po[1005];

int ans[4000],top,ti;

void dfs(int left,int right)

{

    if(left>right)

        return ;

    else if(left==right)

    {

        ti+=po[left];

        ans[top++]=po[left];

    }

    else if(left+1==right)

    {

        ti+=po[right];

        ans[top++]=po[left];

        ans[top++]=po[right];

    }

    else if(left+2==right)

    {

        ti+=po[right]+po[right-1]+po[left];

        ans[top++]=po[left];

        ans[top++]=po[right];

        ans[top++]=po[left];

        ans[top++]=po[left];

        ans[top++]=po[left+1];

    }

    else

    {

        int tp1=po[right]+2*po[left]+po[right-1];

        int tp2=po[left]+po[left+1]*2+po[right];

        if(tp1<=tp2)

        {

            ti+=tp1;

            ans[top++]=po[left];

            ans[top++]=po[right];

            ans[top++]=po[left];

            ans[top++]=po[left];

            ans[top++]=po[right-1];

            ans[top++]=po[left];

        }

        else

        {

            ti+=tp2;

            ans[top++]=po[left];

            ans[top++]=po[left+1];

            ans[top++]=po[left];

            ans[top++]=po[right-1];

            ans[top++]=po[right];

            ans[top++]=po[left+1];

        }

        dfs(left,right-2);

    }

}

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        for(int i=0;i<n;i++)

            scanf("%d",&po[i]);

        sort(po,po+n);

        ti=top=0;

        dfs(0,n-1);

        printf("%d\n",ti);

        for(int i=0;i<top;i+=3)

        {

            if(i+2==top)

                printf("%d %d\n",ans[i],ans[i+1]);

            else if(i+1==top)

                printf("%d\n",ans[i]);

            else

                printf("%d %d\n%d\n",ans[i],ans[i+1],ans[i+2]);

        }

    }

    return 0;

}

  

你可能感兴趣的:(poj)