http://acm.hdu.edu.cn/showproblem.php?pid=5543
题意:现在有一根长度为m的木板和一些小木棒,这些小木棒要放在长木板上并且每一根小木板的重心要在长木板上,即两端的小木棒长度可以露出一半的长(小木棒不可以重叠),当然,也可以不露,问你在符合题意的情况下最大能取到小木棒的价值为多少?
提示:若只有一根小木棒的话,需要预处理,因为只有一根木棒不管怎样它都可以保持平衡。
分析:一开始想着用一个变量去标记已经有几根木棒露出一半长,后来发现行不通,还是用数组标记方便点。。
#include <iostream> #include <stdio.h> #include <string.h> #include <string> #include <vector> #include <algorithm> #include <map> #include <queue> #include <stack> #include <math.h> using namespace std; #define INF 0x3f3f3f3f const int maxn = 4100; typedef long long LL; int len[maxn]; long long value[maxn], dp[maxn][5]; int main() { int T, n, m, t=1; scanf("%d", &T); while(T --) { scanf("%d %d", &n, &m); m *= 2; long long ans = 0; for(int i=1; i<=n; i++) { scanf("%d %lld", &len[i], &value[i]); len[i] *= 2; ans = max(ans, value[i]); } memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; i++) { for(int j=m; j>=len[i]/2; j--) { for(int k=0; k<3; k++) { if(j>=len[i]) dp[j][k]=max(dp[j][k], dp[j-len[i]][k]+value[i]); if(k>0) dp[j][k]=max(dp[j][k], dp[j-len[i]/2][k-1]+value[i]); ans = max(ans, dp[j][k]); } } } printf("Case #%d: %lld\n", t++, ans); } return 0; }