题解 P1926 【小书童——刷题大军】
尝试写个题解 :)
本人蒟蒻一枚,不喜轻喷
以下是对题目解释
-
首先,这道题目是明显的01背包题目
-
所以你就去写了01背包(应该不用教吧)
-状态转移方程还是给了吧,能够让懒懒的你不用往后翻。
-
f[j] = max(f[j],f[j-w[i]] + c[i]);
-
由于神犇小A不同于我等蒟蒻,所以拿到及格分就可以了,所以从前往后扫一次,一旦某个f[i]及格了,就停止做作业(真是勇敢 de 孩纸),于是刷题时间是总时间减去已经用过时间。
-
接着,由于每道题目都是等价的,而小A只追求数量(这样的刷题实际上是没有多大意义的,事倍功半),所以就把题目排序一下(偷懒sort),然后先做时间短的,刷完一道题之后余剩时间减去了这道题目用时。
-
如果时间<=0,那么退出,因为小A得跑去学校了(0秒就到学校了,跑得真快)
-
因为小A已经在上课了,所以请你帮他输出他能够刷题的最大数量。
-
再重复一次,小A真勇敢啊(本题解精髓所在#(滑稽))
-
当然,你会一览我的个人网站(与NOIp无关) http://scris.top/ 的
代码如下
#include<bits/stdc++.h>//万能库
using namespace std;
int n,m,k,r;//无需解释
int a[11];//要刷的题目需要的时间
int w[11];//作业所需时间
int c[11];//作业分值
int f[501] = {0};//表示用f[i]时间能够得到的分数
int stt;//表示余剩下用来刷题的时间
int stn = 0;//已经刷的个数
int main()
{
ios_base::sync_with_stdio(0);//让cin变快 de 黑科技x1
cin.tie(0);//让cin变快 de 黑科技x2
cin>>n>>m>>k>>r;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);//尽量挑时间短的题目去做
for(int i=1;i<=m;i++)
{
cin>>w[i];
}
for(int i=1;i<=m;i++)
{
cin>>c[i];
}
for(int i=1;i<=n;i++)
{
for(int j=r;j>=w[i];j--)//标准01背包写法
{
f[j] = max(f[j],f[j-w[i]] + c[i]);
}
}
for(int i=1;i<=r;i++)
{
if(f[i] >= k)//可以及格了
{
stt = r - i;//已经写作业花去的时间不能刷题了
break;
}
}
for(int i=1;i<=n;i++)
{
stt -= a[i];//刷了一道题
if(stt <= 0) break;//没时间了赶紧跑去学校
stn++;//多刷了一道题,成就感++,rp--
}
cout<<stn<<endl;//输出刷题数量
return 0;
}