题目链接:http://acm.uestc.edu.cn/#/problem/show/1218
题目大意:给出n根木棒的长度和价值,最多可以装在一个长 l 的容器中,相邻木棒之间不允许重叠,且两边上的木棒,可以伸一半的长度在容器外,求最大价值量
解题思路:初看一眼就是01背包,没错就是01背包,但是有个特殊的地方需要处理,就是容器2边的筷子,将容器的长度X2,筷子的长度X2,那么相当于每根筷子的价值,可以被放0,1,2次,再加一层循环来枚举放筷子的价值量
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 typedef long long LL; 15 16 LL dp[4010][3], val[1010], w[1010]; 17 int main() 18 { 19 int t, n, l; 20 scanf("%d", &t); 21 for(int ca = 1; ca <= t; ca++) 22 { 23 scanf("%d %d", &n, &l); 24 LL res = 0; 25 for(int i = 1; i <= n; i++) 26 { 27 scanf("%lld %lld", &w[i], &val[i]); 28 res = max(res, val[i]);//只放一根的最大价值 29 w[i] <<= 1; 30 } 31 l <<= 1; 32 memset(dp, 0, sizeof(dp)); 33 for(int i = 1; i <= n; i++) 34 { 35 for(int j = l; j >= w[i] / 2; j--) 36 { 37 for(int k = 0; k < 3; k++)//有几根木棒是在外面的,最多两根,所以k <= 2 38 { 39 if(k >= 1) 40 dp[j][k] = max(dp[j][k], dp[j-w[i]/2][k-1]+val[i]); //当前木棒放外面 41 if(j >= w[i]) 42 dp[j][k] = max(dp[j][k], dp[j-w[i]][k]+val[i]); //当前木棒全部在里面 43 } 44 } 45 } 46 for(int i = 0; i < 3; i++) 47 res = max(res, dp[l][i]); 48 printf("Case #%d: %lld\n", ca, res); 49 } 50 return 0; 51 }
时间: 2024-10-12 23:49:58