ZOJ - 3211 Dream City

这个其实是个背包问题,把日期看成背包的容量。然后n棵树当成n个物品。

只是在开gao之前要先预处理一下。

假设我们取得由某m棵树组成的最优解。如果先砍的树的b值比后砍的树的b值大,那么我们总能交换这两树砍的顺序而得到更多的钱。所以我们按增加钱币量b值升序将n棵树排序。之后就能gao出来了。

 

 

(看来对于物品放置的顺序是随意的 & 物品的value会变的背包总会蕴含那么些贪心性质的东西)^_^

#include <cstdio> #include <algorithm> #define max(a, b) (a > b ? a : b) using namespace std; const int INF = -99999999; struct Node{ int a, b; bool operator < (const Node &x) const { return b < x.b; } }; Node tree[256]; int dp[256][256]; int main(int argc, char* argv[]) { int T, n, i, j, m; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for(i = 1; i <= n; i++) { scanf("%d", &tree[i].a); } for(i = 1; i <= n; i++) { scanf("%d", &tree[i].b); } sort(tree+1, tree+n+1); fill(dp[0], dp[n+1], INF); dp[0][0] = 0; for(i = 1; i <= n; i++) { for(j = 0; j <= m; j++) { dp[i][j] = dp[i-1][j]; if(j >= 1) { dp[i][j] = max(dp[i-1][j-1]+tree[i].a+tree[i].b*(j-1), dp[i][j]); } } } printf("%d/n", *max_element(dp[n], dp[n]+m+1)); } return 0; }  

你可能感兴趣的:(struct,tree)