您的位置:首页 > 其它

POJ1007过河问题 贪心||DP

2017-04-15 23:29 357 查看
#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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息