• 解题报告:POJ2573 Bridge(分析建模)


    原题链接:POJ2573

    解析:本题没有已知算法模板,需要自己建模。如果想在最短时间内过河,势必要考虑速度最慢的人如何过河,那就需要让速度最快的帮助速度最慢的渡河,这样才可以节约时间。这样问题就可以转化成如何让最慢的人过河才节约时间。设最快的人为a,次快为b,最慢为d,次慢为c,(a<b<c<d)。有两种方案渡河:

    1. a和b先过河,时间为b,a回来,时间为a,c和d渡河,时间为d,b回来,时间为b,这样c和d就成功渡河,所用时间为b+a+d+b = 2*b+a+d
    2. a和c(或d)先渡河,时间为c,a回来,时间为a,a和d渡河,时间为d,a回来,时间为a,c和d成功渡河,时间为c+a+d+a = 2*a+c+d;

    错误报告:

    • 只考虑到第一种情况,以为这就最优方案,思路也没有明确转化成如何让最慢的人渡河,只是简单的自以为找到规律开始做题。
    • 没有考虑到n = 1时情况,此时只需要让这一个人渡河就行了。
    • 过于依赖STL,以至于使用优先队列弄巧成拙。

    代码实例:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a[11111];
    int main()
    {
    	int n;
    	cin >> n;
    	for(int i = 0;i < n;i++)	cin >> a[i];
    	if(n == 1){
    		cout << a[0] << endl << a[0] <<endl;
    		return 0;
    	}
    	sort(a,a+n);
    	int nn = n;
    	int sum = 0;
    	while(n > 3){
    		if(2*a[0] + a[n-2]+a[n-1] < 2*a[1]+a[0]+a[n-1]){
    			sum += 2*a[0] + a[n-2]+a[n-1];
    		}else{
    			sum += 2*a[1]+a[0]+a[n-1];
    		}
    		n -= 2;
    	}
    	if(n == 2)	sum += a[1];
    	else	sum += a[2]+a[0]+a[1];
    	cout << sum << endl;
    	n = nn;
    	while(n > 3){
    		if(2*a[0] + a[n-2]+a[n-1] < 2*a[1]+a[0]+a[n-1]){
    			printf("%d %d
    %d
    %d %d
    %d
    ",a[0],a[n-2],a[0],a[0],a[n-1],a[0]);
    		}else{
    			printf("%d %d
    %d
    %d %d
    %d
    ",a[0],a[1],a[0],a[n-1],a[n-2],a[1]);
    		}
    		n -= 2;
    	}
    	if(n == 2)	printf("%d %d
    ",a[0],a[1]);
    	else printf("%d %d
    %d
    %d %d
    ",a[0],a[2],a[0],a[0],a[1]);
    	return 0;
    }

    《算法设计编程实验》——吴永辉P3

  • 相关阅读:
    OpenEuler 中C与汇编的混合编程
    实验四 Web服务器2
    实验四 Web服务器1
    OpenEuler中C语言中的函数调用测试
    第14章学习笔记(20191213兰毅达)
    第13章学习笔记(20191213兰毅达)
    第12章学习笔记(20191213兰毅达)
    冲刺day5
    Oracle中Sequence使用
    Oracle中dual表的用途
  • 原文地址:https://www.cnblogs.com/long98/p/10352189.html
Copyright © 2020-2023  润新知