ZOJ3211-Dream City(贪心思想+变形的01背包)
Description
JAVAMAN is visiting Dream City and he sees a yard of gold coin trees. There are n trees in the yard. Let's call them tree 1, tree 2 ...and tree n. At the first day, each tree i has ai coins on it (i=1, 2, 3...n). Surprisingly, each tree i can grow bi new coins each day if it is not cut down. From the first day, JAVAMAN can choose to cut down one tree each day to get all the coins on it. Since he can stay in the Dream City for at most m days, he can cut down at most m trees in all and if he decides not to cut one day, he cannot cut any trees later. (In other words, he can only cut down trees for consecutive m or less days from the first day!)
Given n, m, ai and bi (i=1, 2, 3...n), calculate the maximum number of gold coins JAVAMAN can get.
Input
There are multiple test cases. The first line of input contains an integer T (T <= 200) indicates the number of test cases. Then T test cases follow.
Each test case contains 3 lines: The first line of each test case contains 2 positive integers n and m (0 < m <= n <= 250) separated by a space. The second line of each test case contains n positive integers separated by a space, indicating ai. (0 < ai <= 100, i=1, 2, 3...n) The third line of each test case also contains n positive integers separated by a space, indicating bi. (0 < bi <= 100, i=1, 2, 3...n)
Output
For each test case, output the result in a single line.
Sample Input
2 2 1 10 10 1 1 2 2 8 10 2 3
Sample Output
10 21
Hints:
Test case 1: JAVAMAN just cut tree 1 to get 10 gold coins at the first day.
Test case 2: JAVAMAN cut tree 1 at the first day and tree 2 at the second day to get 8 + 10 + 3 = 21 gold coins in all.
有n颗树,每棵树都有固定的初始值,和有增长值,
给出m天,每天只能砍一棵树,那么对与第j天,
如果选择砍掉第i棵树,
那么收获的硬币就是初始值+增长值*(j-1),
怎样砍才能使收获的硬币最多
在做背包前,要先排个序,
可将问题转化为01背包问题。
dp[i][j]表示前i课树,第j天所能取到的最大值。
状态转移方程 :
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+p[i].v1+p[i].v2*(j-1));
#include<cstdio> #include<string> #include<cstdlib> #include<cmath> #include<iostream> #include<cstring> #include<set> #include<queue> #include<algorithm> #include<vector> #include<map> #include<cctype> #include<stack> #include<sstream> #include<list> #include<assert.h> #include<bitset> #include<numeric> #define eps 10e-6 #define INF 999999999 using namespace std; #define max_v 255 struct node { int v1; int v2; }p[max_v]; bool cmp(node a,node b) { return a.v2<b.v2; } int dp[max_v][max_v]; int main() { int t; int n,m; scanf("%d",&t); while(t--) { scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&p[i].v1); } for(int i=1;i<=n;i++) { scanf("%d",&p[i].v2); } sort(p+1,p+1+n,cmp); memset(dp,0,sizeof(dp)); int ans=-INF; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+p[i].v1+p[i].v2*(j-1)); ans=max(ans,dp[i][j]); } } printf("%d\n",ans); } return 0; } /* 题目意思: 有n颗树,每棵树都有固定的初始值,和有增长值, 给出m天,每天只能砍一棵树,那么对与第j天, 如果选择砍掉第i棵树, 那么收获的硬币就是初始值+增长值*(j-1), 怎样砍才能使收获的硬币最多 解题思路:增长快的要放在后面砍会比较有利。 在做背包前,要先排个序, 可将问题转化为01背包问题。 dp[i][j]表示前i课树,第j天所能取到的最大值。 状态转移方程 : dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+p[i].v1+p[i].v2*(j-1)); */
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南