题目描述:
Afandi is herding N sheep across the expanses of grassland when he finds himself blocked by a river. A single raft is available for transportation.
Afandi knows that he must ride on the raft for all crossings, but adding sheep to the raft makes it traverse the river more slowly.
When Afandi is on the raft alone, it can cross the river in M minutes When the i sheep are added, it takes Mi minutes longer to cross the river than with i-1 sheep (i.e., total M+M1 minutes with one sheep, M+M1+M2 with two, etc.).
Determine the minimum time it takes for Afandi to get all of the sheep across the river (including time returning to get more sheep).
输入描述:
On the first line of the input is a single positive integer k,
telling the number of test cases to follow. 1 ≤ k ≤ 5 Each case contains:
* Line 1: one space-separated integers: N and M (1 ≤ N ≤ 1000 , 1≤ M ≤ 500).
* Lines 2..N+1: Line i+1 contains a single integer: Mi (1 ≤ Mi ≤ 1000)
输出描述:
For each test case, output a line with the minimum
time it takes for Afandi to get all of the sheep across the river.
样例输入:
2
2 10
3
5
5 10
3
4
6
100
1
样例输出:
18
50
题意分析:
带n只羊过河,带不同的羊过河会有不同的时间,当带 i 只羊过河时,会消耗前 i 个数的和那么长的时间。
人本身过一次河会消耗m时间,求所有羊过河的最短时间。
解题思路:
把羊的个数看做体积,过河时间看做价值,类似空间为n求最小价值的背包问题。
dp[ i ] 代表送i只羊过河需要的最短时间,每多送一次,需要来回两趟;
转移方程:dp[i] = min(dp[i] , dp[i - j] + sum[j] + 2*m) ;
最后一次不用回,答案为dp[ n ] - m。
#include <stdio.h>
#include <string.h>
#define N 1020
int a[N],dp[N],sum[N];
int min(int a,int b)
{
return a<b? a:b;
}
int main()
{
int t,m,n,i,j;
scanf("%d", &t);
while(t--){
memset(sum , 0 , sizeof(sum));
scanf("%d%d", &n, &m);
for(i=1; i<=n; i++){
scanf("%d", &a[i]);
sum[i] = sum[i-1] + a[i];
}
for(i=1; i<=n; i++)
dp[i] = 99999999;
for(i=1; i<=n; i++)
for(j=0; j<=i; j++)
dp[i] = min(dp[i] , dp[i - j] + sum[j] + 2*m) ;
printf("%d\n", dp[n] - m);
}
return 0;
}