CF 题目选做

  写省选的题目对noip没什么大用 关键是 细节题或者是思考题比较重要 练思维自然是CF比较好了 把我见到的比较好的CF题放上来刷一刷。

LINK:Complete the projects

就是说一个人 初始值为R 有n项工作每项工作有两种属性 a和b 当且仅当 R>=a时可以完成这项任务 且R+=b; 每项任务只能完成一次 问能否把所有工作完成。注:b可能为负。

怎么做?显然对于b>=0的工作我们按照a由小到大的顺序直接做如果有不能完成的任务的话 那便一定不能完成。考虑如何做负值的工作?

想了一下我们不能仅仅按照a的值从大到小做 因为可能出现顺序上的错误 导致答案错误 按照 ai+bi从大到小的顺序么? 经过我的一番操作 发现wa掉了。再次考虑这个顺序?

苦苦思索好多天 发现没认真读题 题目中说道对于完成每一个任务都R都得非负,最后我没判断R的正负... 所以就是按照ai+bi从大到小的顺序的。

当时考的时候我直接想到了 但是没想证明这里来利用微扰法来证明一下。设当前任务排序为 a1+b1,a2+b2...an+bn;

如果对于 ai+bi >aj+bj 来说j排在i前面那么 则有R>=aj 且R-=bj 之后可得 R>=ai; 我们看另一种情况 R>=ai 且 R-=bi 之后又 R>=aj;

好像不太好证明  因为看起来非常的显然 也容易想到,那么不证自明好了.../cy

//#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cstring>
#include<string>
#include<ctime>
#include<cctype>
#include<cstdio>
#include<utility>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
#include<bitset>
#include<vector>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline ll read()
{
    ll x=0,f=1;char ch=getc();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getc();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getc();}
    return x*f;
}
const ll MAXN=210;
ll n,r,top,top1,flag;
struct wy
{
    ll x,y;
}t[MAXN],w[MAXN];
inline ll cmp(wy a,wy b){return a.x<b.x;}
inline ll cmp1(wy a,wy b){return a.x+a.y>b.x+b.y;}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();r=read();
    for(ll i=1;i<=n;++i)
    {
        ll x,y;
        x=read();y=read();
        if(y>=0)t[++top]=(wy){x,y};
        if(y<0)w[++top1]=(wy){x,y};
    }
    sort(t+1,t+1+top,cmp);
    for(ll i=1;i<=top;++i)
    {
        if(t[i].x>r){puts("NO");return 0;}
        r+=t[i].y;
    }
    sort(w+1,w+1+top1,cmp1);
    for(ll i=1;i<=top1;++i)
    {
        if(w[i].x>r){puts("NO");return 0;}
        r+=w[i].y;
    }
    if(r>=0)puts("YES");
    else puts("NO");
    return 0;
}

LINK:加强版

现在是求 我们最多能完成的任务数 这就很有区别了首先对于b>=0我们不一定能全部做完但是还是可以贪心的去做 因为拿不到的不管采取什么方法都拿不到。

考虑如何取 a<0的部分这次我们不能再贪心的选取了 因为 可能当前是能选导致R大大减小 以至于后面选的任务更少了。

但是我们仍可以按照上一道题的排序方式来选取,这样仍可以使得利益最大化...固定了顺序接下来的操作其实就是对于每个任务选或不选了,直接背包的拿取即可。dp一下...

当然和背包不太一样因为 有ai的限制我们状态设为 到第i个任务此时R值为j所做的最多的任务数,这样进行转移即可。只不过这个需要刷表法更容易写。

//#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cstring>
#include<string>
#include<ctime>
#include<cctype>
#include<cstdio>
#include<utility>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
#include<bitset>
#include<vector>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    int x=0,f=1;char ch=getc();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getc();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getc();}
    return x*f;
}
const int MAXN=110,maxn=30010<<1;
int n,r,top,top1,ans,maxx;
int f[MAXN][maxn];//f[i][j]表示到了第i个任务此时还有j所能完成的最大任务数
struct wy
{
    int x,y;
}t[MAXN],w[MAXN];
inline int cmp(wy a,wy b){return a.x<b.x;}
inline int cmp1(wy a,wy b){return a.x+a.y>b.x+b.y;}
int main()
{
    //freopen("1.in","r",stdin);
    n=read();r=read();
    for(int i=1;i<=n;++i)
    {
        int x,y;
        x=read();y=read();
        if(y>=0)t[++top]=(wy){x,y};
        if(y<0)w[++top1]=(wy){x,y};
    }
    sort(t+1,t+1+top,cmp);
    for(int i=1;i<=top;++i)
    {
        if(t[i].x>r)break;
        r+=t[i].y;++ans;
    }
    sort(w+1,w+1+top1,cmp1);
    for(int i=1;i<=top1;++i)
    {
        for(int j=0;j<=r;++j)
        {
            f[i+1][j]=max(f[i+1][j],f[i][j]);
            if(j>=w[i].x&&j>=w[i].y)f[i+1][j+w[i].y]=max(f[i+1][j+w[i].y],f[i][j]+1);
        }
    }
    for(int j=0;j<=r;++j)maxx=max(maxx,f[top1+1][j]);
    printf("%d\n",maxx+ans);
    return 0;
}

原文地址:https://www.cnblogs.com/chdy/p/11488456.html

时间: 2024-10-14 08:12:26

CF 题目选做的相关文章

jzyz 题库 题目选做

题库中也有很多我想不出来的模拟赛的题目.做还是必要的. LINK:水题一道 LINK :ww 原文地址:https://www.cnblogs.com/chdy/p/11488468.html

luogu 题目选做

1025 P1019 单词接龙 往年的\(noip\)原题,纯搜索吧,没啥可讲的,直接暴力枚举,暴力判断就行 没有必要每次都存一个很大的字符串,只要存当前的字符串就行了 每个字符串可以用两次 不能包含关系...好像也没啥了吧 #include <bits/stdc++.h> using namespace std; const int N = 23; int n , ans = -1 , v[N] ; string str[N]; inline int check( string s1 , s

jzyzoj题目选做

1025 P1815 一道贪心,喵? 好吧其实就是个贪心,最大值比较简单,最小值不太好搞看看代码自己理解 #include <bits/stdc++.h> #define LL long long using namespace std; inline int read() { register int x = 0; register char ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while(

20165201 课下作业第十周(选做)

#20165201 课下作业第十周(选做) 相关知识点总结 补做代码运行结果截图 补做代码链接 相关知识点的总结 课上内容的补做,结果截图 教材第十五章的代码分析 补做教材第十五章的编程题目 提交补做的博客作业的连接 主动找老师进行作业答辩 原文地址:https://www.cnblogs.com/cbmwtsl/p/9000384.html

20175209 《MySort》和《IO-myhead》选做

20175209 <MySort>和<IO-myhead>选做 一.MySort 1.题目要求 模拟实现Linux下Sort -t : -k 2的功能. 要有伪代码,产品代码,测试代码(注意测试用例的设计) 参考 Sort的实现.提交博客链接. 2.设计思路 题目中要求为对第二列进行排序,个人设计时希望能够控制对所有列进行排序,因此需要在命令行中输入待排序的列号(这里存在一些小问题在后面问题中说明) 对于给定的字符数组无法直接进行排序,采用split方法将每一行分解后将带排序的列中

MySort(选做)的实现

MySort(选做)的实现 题目内容 注意:研究sort的其他功能,要能改的动代码,需要答辩 模拟实现Linux下Sort -t : -k 2的功能. 要有伪代码,产品代码,测试代码(注意测试用例的设计) 参考 Sort的实现.提交博客链接. 代码框架(题目给出) import java.util.*; public class MySort { public static void main(String[] args) { String[] toSort = {"aaa:10:1:1&quo

课后选做题-MyOD

课后选做题-MyOD od命令的了解 功能 od命令用于将指定文件内容以八进制.十进制.十六进制.浮点格式或ASCII编码字符方式显示,通常用于显示或查看文件中不能直接显示在终端的字符.od命令系统默认的显示方式是八进制,名称源于Octal Dump. 常见的文件为文本文件和二进制文件.od命令主要用来查看保存在二进制文件中的值,按照指定格式解释文件中的数据并输出,不管是IEEE754格式的浮点数还是ASCII码,od命令都能按照需求输出它们的值. 语法 od 参数 -a 此参数的效果和同时指定

20175325 实现mypwd(选做,加分)

20175325 实现mypwd(选做,加分) 一.题目内容: 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 二.步骤: 功能:查看"当前工作目录"的完整路径 使用man命令查看pwd pwd的实现 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 man -k current directory man getcwd 实现与测试mypwd 三.测试代码: int get_nam

[SDOI2016]部分题选做

听说SDOI蛮简单的,但是SD蛮强的.. 之所以是选做,是因为自己某些知识水平还不到位,而且目前联赛在即,不好花时间去学sa啊之类的.. bzoj4517 数论题,我这种不会错排的数论白痴都能手推出来,这题应该谁都能写吧. #include<cstdio> #include<cstring> #include<algorithm> #define mo 1000000007 #define ll long long #define N 1000100 using nam