E题 NIH Budge
题目连接:热身赛E题链接
题解:
这个题告诉你了一定的金额,你需要用一定的金额去赞助科研医学,每个科研药物都有对应的金额和相应金额下可以救助的人,这个题让你在一定规格的金额下,尽最大成度的使被救的人增多。
其实这就是动态规划DP
是01背包的简单变形,其实本质上来说就是01背包
由一维动态数组规划得到
下面上01背包的模板:
int val[maxn];
int cost[maxn];
int dp[maxn];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&v);
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&cost[i]);
}
for(int i=0;i<=v;i++)
{
dp[i]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=v;j>=cost[i];j--)
{
dp[j]=max(dp[j],dp[j-cost[i]]+val[i]);
}
}
int ans=0;
for(int i=1;i<=v;i++) ans=max(ans,dp[i]);
printf("%d\n",ans);
}
return 0;
}
精华的部分:
for(int i=1;i<=n;i++)
{
for(int j=v;j>=cost[i];j--)
{
dp[j]=max(dp[j],dp[j-cost[i]]+val[i]);
}
}
该题就是一个分组背包,在01背包的基础上再增加一层for循环
大佬的分组背包博客
for 所有的组k
for v=V..0
for 所有的i属于组k
f[v]=max{f[v],f[v-c[i]]+w[i]}
基本上就是三层for循环加上01背包的模板
#include<bits/stdc++.h>
#include<algorithm>
#define ll long long
using namespace std;
//01背包
const int k=4;
const int maxn=100;
int val[maxn][k+1];
int cost[maxn][k+1];
int dp[100000];
int main()
{
int m;
cin>>m;
for(int e=0;e<m;e++)
{
int n,v;
cin>>n>>v;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
cin>>cost[i][j];
cin>>val[i][j];
}
}
for(int i=0;i<=v;i++)
{
dp[i]=0;
}
for(int i=1;i<=n;i++)
{
for(int j=v;j>=0;j--)
{
for(int d=1;d<=k;d++)
{
if(j>=cost[i][d])
{
dp[j]=max(dp[j],dp[j-cost[i][d]]+val[i][d]);
}
}
}
}
cout<<"Budget #"<<e+1<<": Maximum of "<<dp[v]<<" lives saved."<<endl<<endl;
}
}
该题代码精华部分:
for(int i=1;i<=n;i++)
{
for(int j=v;j>=0;j--)
{
for(int d=1;d<=k;d++)
{
if(j>=cost[i][d])
{
dp[j]=max(dp[j],dp[j-cost[i][d]]+val[i][d]);
}
}
}
}