首页 > 代码库 > uestc1218_变形01背包

uestc1218_变形01背包

题目链接: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 0x3f3f3f3f14 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 <= 238                 {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 }
View Code

 

uestc1218_变形01背包