dp的思路和贪心思路是一样的, 只不过是用dp模拟了贪心的过程,我的贪心的代码不够简洁。
思路:
首先先让1和 2 走过去。
每次选择两种方式的一种
1:让 1 载着最慢的人走过去,然后再让 1 回来
2:先让 1 过去,让最慢的载着次慢的回来,再让2 过去接 1 。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1010;
int t[N];
int main()
{
int n; cin >> n;
while(n --)
{
int a, res = 0; cin >> a;
for(int i = 1; i <= a; i ++) scanf("%d", t + i);
if(a == 1)
{
cout << t[1] << endl;
continue;
}
sort(t + 1, t + a + 1);
res += t[2];
if(a % 2 == 0)
{
for(int i = a; i > 2; i -= 2)
{
if(t[i] + t[i - 1] + 2 * t[1] < 2 * t[2] + t[1] + t[i])
{
res += t[i] + t[i - 1] + 2 * t[1];
}
else res += (2 * t[2] + t[1] + t[i]);
}
cout << res << endl;
}
else
{
for(int i = a; i > 3; i -= 2)
{
if(t[i] + t[i - 1] + 2 * t[1] < 2 * t[2] + t[1] + t[i])
{
res += t[i] + t[i - 1] + 2 * t[1];
}
else res += 2 * t[2] + t[1] + t[i];
}
cout << res + t[1] + t[3] << endl;///395
}
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010, INF = 0x3f3f3f3f;
int a[N], dp[N];
int main()
{
int n; cin >> n;
while(n --)
{
memset(dp, 0x3f, sizeof dp);
int t; cin >> t;
for(int i = 1; i <= t; i ++) scanf("%d", a + i);
sort(a + 1, a + t + 1);
dp[1] = a[1], dp[2] = a[2];
for(int i = 3; i <= t ; i ++)
dp[i] = min(a[1] + a[i] + dp[i - 1], dp[i - 2] + 2 * a[2] + a[i] + a[1]);
cout << dp[t] << endl;
}
return 0;
}