AreYouBusy
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AreYouBusy相关的知识,希望对你有一定的参考价值。
题意:
给你n个工作集合,给你T的时间去做它们。给你m和s,说明这个工作集合有m件事可以做,它们是s类的工作集合(s=0,1,2,s=0说明这m件事中最少得做一件,s=1说明这m件事中最多只能做一件,s=2说明这m件事你可以做也可以不做)。再给你ci和gi代表你做这件事要用ci的时间,能获得gi的快乐值。求在T的时间内你能获得的最大快乐值。
题解:
我们设dp[i][j]表示处理完前i组工作集,所用时间小于j的快乐值
dp[i]表示的是第i组的结果,每组相对独立,
所以对于每一组情况,我们就可以将dp看作是一维数组,只考虑第二维j,考虑第一维仅为需要继承状态时
我们分析三种集合:
- 至少选一项。在开始时dp初始化为负无穷,这样是为了保证不会出现都不不选的情况,负无穷相当于这个情况不合法即未选
转移方程:
dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x]));
dp[i][j]表示不选这个工作
dp[i][j-w[x]]+p[x]:表示选择当前工作,且不是第一次取(为什么这个能保证不是第一次取?因为我们一开始将dp[i][…]赋值为负无穷,如果dp[i][j-w[x]]没被选过就还是负无穷,则整个式子取最大就跟他无关,如果被选过,则dp[i][j-w[x]]为正数)
dp[i-1][j-w[x]]+p[x]:第一次在本组中选物品,由于dp初始化为负无穷,所以状态的转移只能从上一组的结果中得知,这样可以保证得到全局最优解
这样,当有一组无法完成时,最后的答案就是负无穷
- 最多选一项,要么不选,要么就是第一次选
为了保证全局最优解,dp[i][j]继承上一组的状态
第一次选的话,和第一种集合的情况一样
dp[i][j]=max(dp[i][j],dp[i-1][j-w[x]]+p[x]);
- 任意选就是01背包
为了保证全局最优解,dp[i][j]继承上一组的状态
dp[i][j]=max(dp[i][j],dp[i][j-w[x]]+p[x]);
这里的dp是被压缩了一维的,这里的dp[][j]中的j等于01背包的一维数组dp[j],
dp[i][]中的i只是表示第i组的情况
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int n,m,sum;
int w[110],p[110];
int dp[110][110];
int main(){
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&sum)){
memset(dp,0,sizeof(dp));
int i,j,k,g;
for(i=1;i<=n;i++)
{
scanf("%d%d",&m,&g);
for(k=1;k<=m;k++)
scanf("%d%d",&w[k],&p[k]);
if(g==0){//至少选一个
for(j=0;j<=sum;j++) //当前组初始化
dp[i][j]=-INF;
for(k=1;k<=m;k++)
for(j=sum;j>=w[k];j--)
dp[i][j]=max(dp[i][j],max(dp[i][j-w[k]]+p[k],dp[i-1][j-w[k]]+p[k]));
}else if(g==1){//最多选一个
for(j=0;j<=sum;j++) //当前组初始化
dp[i][j]=dp[i-1][j];
for(k=1;k<=m;k++)
for(j=sum;j>=w[k];j--)
dp[i][j]=max(dp[i][j],dp[i-1][j-w[k]]+p[k]);
//dp[i-1][j-w[k]]
//j-w[k]<j
}else if(g==2){//自由选择
for(j=0;j<=sum;j++) //当前组初始化
dp[i][j]=dp[i-1][j];
for(k=1;k<=m;k++)
for(j=sum;j>=w[k];j--)
dp[i][j]=max(dp[i][j],dp[i][j-w[k]]+p[k]);
}
}
dp[n][sum]=max(dp[n][sum],-1); //没有完成任务的值都为负的,做输出调整,输出-1
printf("%d\\n",dp[n][sum]);
}
return 0;
}
以上是关于AreYouBusy的主要内容,如果未能解决你的问题,请参考以下文章