15.3.14 DP练习2
拦截导弹
题目
某国为了防御敌国的导弹突击,发展出一种导弹拦截系统。
可是这样的导弹拦截系统有一个缺陷:尽管它的第一发炮弹可以到达随意的高度。可是以后每一发炮弹都不能高于前一发的高度。
某天,雷达捕捉到敌国的导弹来袭。因为该系统还在试用阶段。所以仅仅有一套系统,因此有可能不能拦截全部的导弹。
输入数据: 
第一行为一个整数N。表示飞来的导弹个数。N<=100000 
第二行为N个整数,依次表示导弹飞来的高度。高度数据为不大于30000的正整数。
输出数据: 
第一行。输出计算这套系统最多能拦截多少导弹 
第二行。输出要拦截全部导弹最少要配备多少套这样的导弹拦截系统。
输入文件:missile.in 
8 
389 207 155 300 299 170 158 65
输出文件:missile.out  
6 2
分析
求个最长不上升子序列长度。一个上升子序列长度。 
因为数据范围奇葩,所以用单调栈乱搞到nlog(n)
代码
#include <cstdio>
#include <string>
#include <algorithm>
#define R1(i,n) for(register int i=1;i<=n;++i)
using namespace std;
template <class T> inline void read(T&x){
    bool f=false;char ch;
    for(ch=getchar();ch<=32;ch=getchar());
    if (ch=='-')f=true,ch=getchar();
    for(x=0;ch>32;ch=getchar()) x=x*10+ch-'0';
    if(f)x=-x;
}
template <class T> inline void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x + '0');
    else write(x / 10),putchar(x%10+'0');
}
template <class T> inline void writeln(T x){
    write(x);puts("");
}
void setIO(string t){
string a=t+".in",b=t+".out";
freopen(a.c_str(),"r",stdin);
freopen(b.c_str(),"w",stdout);
}
int n,cnt;
int s1[100010],s2[100010],temp;
int main(){
    setIO("missile");
    read(n);
    int top1=0,top2=0;
    s1[0]=-1,s2[0]=0x3f3f3f3f;
    R1(i,n){
        read(temp);
        if(temp>s1[top1])s1[++top1]=temp;
        else{
            int _l=1,_r=top1;
            int mid;
            while(_l<=_r){
                mid=(_l+_r)/2;
                if(temp>s1[mid])_l=mid+1;
                else _r=mid-1;
            }
            s1[_l]=temp;
        }
        if(temp<=s2[top2])s2[++top2]=temp;
        else{
            int _l=1,_r =top2;
            int mid;
            while(_l<=_r){
                mid=(_l+_r)/2;
                if (temp<=s2[mid])_l=mid+1;
                else _r=mid-1;
            }
            s2[_l]=temp;
        }
    }
writeln(top2),writeln(top1);
return 0;
}
整数划分
题目
怎样把一个正整数N(N长度<20)划分为M(M>1)个部分,使这N个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。
输入数据: 
第一行一个正整数T(T<=10000)。表示有T组数据。 
接下来T行每行两个正整数N,M。
输出数据: 
对于每组数据 
第一行输出最大值。 
第二行输出划分方案,将N按顺序分成M个数输出,两个数之间用空格格开。
例子 
输入文件:separate.in 
1 
199 2
输出文件:separate.out 
171 
19 9
WA的代码= =
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#define R1(i,n) for(register int i=1;i<=n;++i)
#define R0(i,n) for(register int i=0;i<n;++i)
#define r(i,s,t) for(register int i=s;i<=t;++i)
#define  cl(a,m) memset(a,m,sizeof(a))
using namespace std;
template <class T> inline void read(T&x){
    bool f=false;char ch;
    for(ch=getchar();ch<=32;ch=getchar());
    if (ch=='-')f=true,ch=getchar();
    for(x=0;ch>32;ch=getchar()) x=x*10+ch-'0';
    if(f)x=-x;
}
template <class T> inline void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x + '0');
    else write(x / 10),putchar(x%10+'0');
}
template <class T> inline void writeln(T x){
    write(x);puts("");
}
void setIO(string t){
string a=t+".in",b=t+".out";
freopen(a.c_str(),"r",stdin);
freopen(b.c_str(),"w",stdout);
}
long long g[500][500],f[500][500],v[500][500];char s[23];
void print(int p,int d){
    if(d==0)return;
    print(g[p][d],d-1);
    r(i,g[p][d],p-1)write(s[i]-'0');
    putchar(' ');
}
int m,t;
int main(){
    setIO("separate");
    read(t);
    while(t--){
        scanf("%s",s);
        read(m);
        int l=strlen(s);
        R1(i,l){
            int sum=0;
            r(j,i,l){
                //if(s[j-1]>0)
                sum=sum*10+s[j-1]-'0',
                v[i][j]=sum;
            }
        }
        cl(f,-1);
        f[0][0]=1;
        R1(i,l)
        R1(j,min(i,m))
        R1(k,i){
            if(f[k-1][j-1]*v[k][i]>f[i][j]){
                f[i][j]=f[k-1][j-1]*v[k][i];
                g[i][j]=k-1;
            }
        }
        writeln(f[l][m]);
        print(l,m);
        puts("");
    }
    return 0;
}
快餐问题
题目
Peter近期在R市开了一家快餐店,为了招揽顾客,该快餐店准备推出一种套餐,该套餐由A个汉堡,B个薯条和C个饮料组成。价格廉价。为了提高产量,Peter从著名的麦当劳公司引进了N条生产线。全部的生产线都可以生产汉堡,薯条和饮料,因为每条生产线每天所能提供的生产时间是有限的、不同的,而汉堡。薯条和饮料的单位生产时间又不同。这使得Peter非常为难,不知道怎样安排生产才干使一天中生产的套餐产量最大。请你编一程序。计算一天中套餐的最大生产量。
为简单起见,如果汉堡、薯条和饮料的日产量不超过100个。
输入数据: 
第一行为三个不超过100的正整数A、B、C中间以一个空格分开。 
第二行为3个不超过100的正整数p1,p2,p3分别为汉堡。薯条和饮料的单位生产耗时。中间以一个空格分开。 
第三行为为一个整数N (0<=0<=10),表示有N条流水线 
第四行为N个不超过10000的正整数,当中Ti表示第i条生产流水线每天提供的生产时间,中间以一个空格分开。
输出数据: 
仅一行,即每天套餐的最大产量。
输入文件:meal.in 
2 2 2 
1 2 2 
2 
6 6
输出文件:meal.out 
1
代码
#include <cstdio>
#include <string>
#include <algorithm>
#define R1(i,n) for(register int i=1;i<=n;++i)
using namespace std;
template <class T> inline void read(T&x){
    bool f=false;char ch;
    for(ch=getchar();ch<=32;ch=getchar());
    if (ch=='-')f=true,ch=getchar();
    for(x=0;ch>32;ch=getchar()) x=x*10+ch-'0';
    if(f)x=-x;
}
template <class T> inline void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x + '0');
    else write(x / 10),putchar(x%10+'0');
}
template <class T> inline void writeln(T x){
    write(x);puts("");
}
void setIO(string t){
string a=t+".in",b=t+".out";
freopen(a.c_str(),"r",stdin);
freopen(b.c_str(),"w",stdout);
}
int A,B,C,p1,p2,p3,n,t[20],ans;
int f[20][101][101][101];
int main(){
    setIO("meal");
    //f[i][a][b][c] :  前i条流水线, 生产a个汉堡,b个薯条,c个饮料的最大套餐产量
    read(A),read(B),read(C);
    read(p1),read(p2),read(p3);
    if(!p1 && !p2 && !p3){writeln(0);return 0;}
    read(n);
    R1(i,n)read(t[i]),t[i]+=t[i-1];
//  R1(i,n)R1(j,n)R1(k,n)f[0][i][j][k]=0;
    R1(i,n)
        for(register int a=A;a*p1<=t[i]&&a<=100;++a)
            for(register int b=B;a*p1+b*p2<=t[i]&&b<=100;++b)
                for(register int c=C;a*p1+b*p2+c*p3<=t[i]&&c<=100;++c){
                    ans=max(ans,f[i][a][b][c]=max(f[i][a-A][b-B][c-C]+1,max(f[i-1][a-A][b-B][c-C]+1,f[i][a][b][c])));
                    //if(f[i][a][b][c])printf("f[%d][%d][%d][%d] = %d\n",i,a,b,c,f[i][a][b][c]);
                }
writeln(ans);
}
物品装箱问题
题目
设有n种物品,记作A1、A2、…、An,相应于每一个Ai(1<=i<=n)都有一个重量Awi和价值Avi(重量和价值都为正整数)。
另外,相应于每一个Ai,都有一件可取代它的“代用品”Bi,Bi的重量和价值分别为Bwi和Bvi。
本题的任务是:选择这n件物品或其代用品的一个子集装进背包,使总重量不超过给定重量TOT,同一时候使总价值VAL最高。装填的第I步,要么装入Ai。要么装入Bi,要么Ai和Bi都不装。
输入数据: 
第一行:n TOT ,n<=100, TOT<=10000 
第二行:AW1 A v1 B W1 Bv1 
第三行:AW2 A v2 B W2 Bv2 
…… 
第n+1行:AWn A vn B Wn Bvn
输入数据: 
仅仅有一个数为最大的价值
输入文件:box.in 
4 20 
8 20 12 31 
2 3 9 20 
13 31 11 12 
8 9 13 36
输出文件:box.out 
40
分析
01背包 
三选一乱搞
代码
#include <cstdio>
#include <string>
#include <algorithm>
#define mn 200
#define mt 10020
#define R1(i,n) for(register int i=1;i<=n;++i)
using namespace std;
template <class T> inline void read(T&x){
    bool f=false;char ch;
    for(ch=getchar();ch<=32;ch=getchar());
    if (ch=='-')f=true,ch=getchar();
    for(x=0;ch>32;ch=getchar()) x=x*10+ch-'0';
    if(f)x=-x;
}
template <class T> inline void write(T x){
    if(x<0)putchar('-'),x=-x;
    if(x<10)putchar(x + '0');
    else write(x / 10),putchar(x%10+'0');
}
template <class T> inline void writeln(T x){
    write(x);puts("");
}
void setIO(string t){
string a=t+".in",b=t+".out";
freopen(a.c_str(),"r",stdin);
freopen(b.c_str(),"w",stdout);
}
int n,tot;
int f[mt],a_w[mn],a_v[mn],b_w[mn],b_v[mn];
int main(){
    setIO("box");
    read(n),read(tot);
    R1(i,n)read(a_w[i]),read(a_v[i]),read(b_w[i]),read(b_v[i]);
    R1(i,n)for(register int j=tot;j>=min(a_w[i],b_w[i]);--j){
        f[j]=(j>=a_w[i]?
max(f[j],f[j-a_w[i]]+a_v[i]):f[j]);
        f[j]=(j>=b_w[i]? max(f[j],f[j-b_w[i]]+b_v[i]):f[j]);
    }
    writeln(f[tot]);
}
又是颓废的一天= = 
队长又要喷我了orz
15.3.14 DP练习2的更多相关文章
- 9.14 DP合集水表
		
9.14 DP合集水表 关键子工程 在大型工程的施工前,我们把整个工程划分为若干个子工程,并把这些子工程编号为 1. 2. --. N:这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某 ...
 - Html5 reset表 2015年1月7日15:02:14
		
/* HTML5 Reset :: style.css ---------------------------------------------------------- We have learn ...
 - Java 15 正式发布, 14 个新特性,刷新你的认知!!
		
JDK 15 2020/09/15 如期而至! 这个时间牛逼啊,和苹果发布会同天? OracleJDK 15 发布地址: https://www.oracle.com/java/technologie ...
 - UVALive 6908---Electric Bike(DP或记录型深搜)
		
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
 - HDU5834 Magic boy Bi Luo with his excited tree(树形DP)
		
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5834 Description Bi Luo is a magic boy, he also ...
 - hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)
		
题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: ...
 - [ An Ac a Day ^_^ ] hdu 1003 dp
		
超时还有可能是数组开小了…… #include<stdio.h> #include<iostream> #include<algorithm> #include&l ...
 - UVALive 6908 Electric Bike dp
		
Electric Bike 题目连接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8 ...
 - 区间DP(总结)
		
学长一晚上的耐心讲解,使我明白区间DP这么高级的东西,还是挺容易的.也就是在一段区间内的动态规划. 下面用例题进行总结. 例题:石子归并. 描述 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石 ...
 
随机推荐
- Verilog语法
			
语法子集很小,易用. 模块:module…endmodule 端口:input,output,inout(双向特殊) inout比较难用,有一张真值表,需要大家观察后书写,基本原则就是输入时一定是高阻 ...
 - mongodb多表查询(附带pymongo实例)
			
mongodb有$lookup可以做多表查询 举个例子 数据如下 db.orders.insert([ { , , }, { , , }, { } ]) db.inventory.insert([ { ...
 - Mapreduce 测试自带实例 wordcount
			
2.7.3版本的hadoop: jar程序所在目录:$HADOOP_HOME/shar/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar 1.本 ...
 - 云计算之路-试用Azure:制作虚拟机自定义镜像
			
虚拟机自定义镜像(Image)是一个很有用的功能,可以在一台虚拟机上配置好基本的系统环境,然后做个镜像,以后创建虚拟机直接从这个镜像创建,会省掉很多重复的配置工作. 阿里云与UCloud都有这个功能, ...
 - IOS 开发学习33 使用sqlite3
			
sqlite3 命令行简单使用 sqlite3 路径 //打开数据库路径连接 select * from sqlite_master where type="table"; //显 ...
 - python之sqlalchemy基本
			
一.SQLAlchemy 1.sqlalchemy是一个ORM框架,它本身无法操作数据库,需要依赖pymysql.MySQLdb,mssql等第三方插件 2.安装: pip install SQLAl ...
 - android回调函数
			
在我们进行android开发的时候,常常遇到一些回调函数,当中,我们最常常使用的回调就是,当我们对一个组件设置监听的时候,事实上就相对于设置的回调函数.比如: Button btn = (Button ...
 - 算法笔记_094:蓝桥杯练习 矩阵相乘(Java)
			
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 小明最近在为线性代数而头疼,线性代数确实很抽象(也很无聊),可惜他的老师正在讲这矩阵乘法这一段内容. 当然,小明上课打瞌睡也没问题,但线性 ...
 - Java基础——线程总结
			
Java基础--线程总结 一.线程是什么? 线程:一个程序里不同的运行路径. 二.怎样创建线程? 两种方法创建线程: 第一种 (1)定义详细功能类实现Runnable接口,能够多次调用而实现数据共享 ...
 - Excle中range的一些用法
			
以下是一些range的简单用法 Sub aa() '-=============================================== '给B列设置填充颜色为黄色 Range(" ...