POJ1007过河问题 贪心||DP

来源:互联网 发布:网络性质的公司 编辑:程序博客网 时间:2024/05/01 16:23
#include <iostream>#include <algorithm>using namespace std;int main(){    int T;    cin >> T;    int n;    int a[1007];//穿梭速度    //贪心    while(T--){        cin >> n;        for(int i = 0; i < n; i++)            cin >> a[i];        sort(a, a + n);//按过河耗费时间从小到大排序        int ans = 0;        while(n > 3){            //每次过河都有两种方案可选,然后取其最小值(过河方案不是从一而终的,而是动态的选择,即不能每次都用同一个过河方案)            //1.最快的和次快的过去,最快回,最慢的和次慢的过去,次快回 -> 过去两个,最慢和次慢            //2.最快的和最慢的过去,最快回,最快的和次慢的过去,最快回 -> 过去两个,最慢和次慢            //相当于比较的是"2 * a[1] + a[0] + a[n - 1]"和"2 * a[0] + a[n - 1] + a[n - 2]",都是把最慢的和次慢的送过去,即最后两个,然后n就自减2,进行下一次循环            ans += min(a[1] + a[0] + a[n - 1] + a[1], a[n - 1] + a[0] + a[n - 2] + a[0]);            n -= 2;        }        if(n == 3)            ans += a[1] + a[0] + a[2];//只剩三个时不管用哪种方案,耗费时间都相同        else if(n == 2)            ans += a[1];//只剩两个时取最大者        else if(n == 1)            ans += a[0];//只剩一个时没得选        cout << ans << endl;    }}


#include <iostream>#include <algorithm>using namespace std;int main(){    int T;    cin >> T;    int n;    int a[1007];//穿梭速度    //dp写法    int dp[1007];    while(T--){        cin >> n;        for(int i = 0; i < n; i++)            cin >> a[i];        sort(a, a + n);//按过河耗费时间从小到大排序        int ans = 0;        dp[0] = a[0];        dp[1] = a[1];        dp[2] = a[0] + a[1] + a[2];        for(int i = 3; i < n; i++)            //case_1:最快的和次快的过去,最快回,最慢的和次慢的过去,次快回            //比前两次多个 最慢的,两个次快的和最快的            //case_1 = dp[i - 2] + a[1] + a[0] + a[i] + a[1];            //case_2:最快的和最慢的过去,最快回            //比上次多个 最快的和最慢的            //case_2 = dp[i - 1] + a[i] + a[0];            //其实case_2也可以写成dp[i - 2] + a[i] + a[0] + a[i - 1] + a[0]            dp[i] = min(dp[i - 2] + a[1] + a[0] + a[i] + a[1], dp[i - 1] + a[i] + a[0]);            //dp[i] = min(dp[i - 2] + a[1] + a[0] + a[i] + a[1], dp[i - 2] + a[i] + a[0] + a[i - 1] + a[0]);        cout << dp[n - 1] << endl;    }}


0 0
原创粉丝点击