题意:给你n个工作集合,给你T的时间去做它们。给你m和s,说明这个工作集合有m件事可以做,它们是s类的工作集合(s=0,1,2,s=0说明这m件事中最少得做一件,s=1说明这m件事中最多只能做一件,s=2说明这m件事你可以做也可以不做)。再给你ci和gi代表你做这件事要用ci的时间,能获得gi的快乐值。求在T的时间内你能获得的最大快乐值。

思路:分三类各自求即可。0的时候必须更新,1的时候最多更新一次,2的时候正常01背包。

#include<bits/stdc++.h>
#define s first
#define e second
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
using namespace std;
const int maxn=;
const int inf=1e9;
int dp[maxn],tmp[maxn],c[maxn],g[maxn],T,M;
void solve0() //at least
{
rep(i,,T) tmp[i]=-inf;
rep(i,,M)
rep2(j,T,c[i]){
tmp[j]=max(tmp[j],max(dp[j-c[i]]+g[i],tmp[j-c[i]]+g[i]));
}
rep(i,,T) dp[i]=tmp[i];
}
void solve1() //at most
{
rep(i,,T) tmp[i]=dp[i];
rep(i,,M)
rep2(j,T,c[i])
dp[j]=max(tmp[j-c[i]]+g[i],dp[j]);
}
void solve2() //free
{
rep(i,,M)
rep2(j,T,c[i])
dp[j]=max(dp[j-c[i]]+g[i],dp[j]);
}
int main()
{
int N,S,ans;
while(~scanf("%d%d",&N,&T)){
memset(dp,,sizeof(dp));
ans=-;
rep(i,,N){
scanf("%d%d",&M,&S);
rep(j,,M) scanf("%d%d",&c[j],&g[j]);
if(S==) solve0();
if(S==) solve1();
if(S==) solve2();
}
ans=max(ans,dp[T]);
printf("%d\n",ans);
}
return ;
}

最新文章

  1. my_strlen()
  2. Runner站立会议01
  3. C++ 类的静态成员详细讲解
  4. Paramiko 模块使用
  5. K2上海总部技术培训分享笔记
  6. Android模仿QQ空间图片上传——原理
  7. OpenLayers3 online build
  8. 利用PC创建一个无线接入点
  9. C# LINQ详解(一)
  10. Android 获取图片资源的4种方式
  11. 关于 iOS 基础动画
  12. 【js 编程艺术】小制作四
  13. Hbuilder中添加Babel自动编译
  14. Java高级篇(四)——反射
  15. django rest framework(3)
  16. 第一篇——Struts2的工作原理及HelloWorld简单实现
  17. svn本地如何切换账号
  18. npm 查看全局安装过的包
  19. Linux-&gt;卸载Mysql方法总结
  20. Android之Zxing二维码扫描图片拉伸

热门文章

  1. 一段隐藏文字的css代码,记录下
  2. odoo controller 继承
  3. Kubernetes集群
  4. MATLAB爬虫爬取股票数据
  5. python ---socket初识
  6. centos实现三个节点高可用
  7. HTML文件直接在浏览器打开和本地服务器localhost打开有什么区别?
  8. rename file
  9. JavaScript克隆数组
  10. Oracle数据库之初识部分知识