• poj 1700 过河问题 贪心法


    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    /*
    贪婪法:
    1)当人数<3时:直接过
    2)当人数=3时:假设为a,b,c.(升序)
    如果用最小的来送:c+a+b=c+b+a
    如果大的一起过:c+b+b=c+2b.
    所以这个时候用小的来送.
    3)当人数=4时,a,b,c,d(升序)
    如果用最小的来送:d+a+c+a+b=d+c+b+2a
    如果先让最小的两个过河,再让其中一个回来,
    让最大的两个过河,再让前一步过去留下的那个回来,
    再让最小的2个过河
    也就是说小的两个过去2次,再单独回来一次.
    2b+b+a+d=d+3b+a 
    当d+c+b+2a<=d+3b+a时,也就是c-2b+a<=0时,第一种方法过.
    否则用另外一种办法
    4)当人数>4时,a,b,..,c,d(升序)
    过去,回来,过去,回来(船要回来),让最大的2个过去.
    很笨的时间是d+c+c+a=d+2c+a(所有时间都写出来后会发现时最慢的)
    如果让最小的来送:d+a+c+a=d+c+2a
    否则:b+b+a+d=d+2b+a
    如果d+c+2a<=d+2b+a,也就是c-2b+a<=0时,第一种方法过
    */
    
    int main()
    {
    	//freopen("in.txt", "r", stdin);
    	int p[1005],t,n;
    	cin>>t;
    	while(t--)
    	{
    		cin>>n;
    		int i = 0;
    		while(i < n)
    			cin>>p[i++];
    		sort(p, p + n);//左闭右开
    		int sum = 0;
    		while(n)
    		{
    			if(n == 1)
    			{
    				sum += p[0];
    				n = 0;
    			}
    			else if(n == 2)
    			{
    				sum += p[1];
    				n = 0;
    			}
    			else if(n == 3)
    			{
    				sum += (p[0] + p[1] + p[2]);
    				n = 0;
    			}
    			else if(n == 4)
    			{
    				if(p[2] - 2 * p[1] + p[0] <= 0)
    					sum += (p[3] + p[2] + p[1] + 2 * p[0]);
    				else
    					sum += (p[3] + 3 * p[1] + p[0]);
    				n = 0;
    			}
    			else
    			{
    				if(p[n - 2] - 2 * p[1] + p[0] <= 0)
    					sum += (p[n - 1] + p[n - 2] + 2 * p[0]);
    				else
    					sum += (p[n - 1] + 2 * p[1] + p[0]);
    				n -= 2;
    			}
    		}
    		cout<<sum<<endl;
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    error MSB8031(将vs2010的工程用vs2013打开时出的错)
    MFC如何使控件大小随着对话框大小自动调整
    基于MFC对话框程序中添加菜单栏 (CMenu)
    mfc改变对话框窗口大小
    MFC设置对话框大小
    uart与usart区别
    uart接口介绍和认识
    USB引脚属性
    使用百度云服务器BCC搭建网站,过程记录
    linux下文件的复制、移动与删除命令为:cp,mv,rm
  • 原文地址:https://www.cnblogs.com/steady/p/1942555.html
Copyright © 2020-2023  润新知