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;
}

  

转载于:https://www.cnblogs.com/tmeteorj/archive/2012/09/06/2674186.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值