洛谷打卡 Day4
题目描述
现在absi2011拿出了x个迷你装药物(嗑药打人可耻….),准备开始与那些人打了
由于迷你装一个只能管一次,所以absi2011要谨慎的使用这些药,悲剧的是,没到达最少打败该人所用的属性药了他打人必输>.<所以他用2个药去打别人,别人却表明3个药才能打过,那么相当于你输了并且这两个属性药浪费了。
现在有n个好友,有输掉拿的经验、赢了拿的经验、要嗑几个药才能打过。求出最大经验(注意,最后要乘以5)
输入格式
第一行两个数,n和x
后面n行每行三个数,分别表示输了拿到的经验(lose[i])、赢了拿到的经验(win[i])、打过要至少使用的药数量(use[i])。
输出格式
一个整数,最多获得的经验
输入输出样例
输入
6 8
21 52 1
21 70 5
21 48 2
14 38 3
14 36 1
14 36 2
输出
1060
一道典型01背包 不过要注意即使不嗑药 也有价值。 即不选时也有价值。
题解
#include<cstdio>
using namespace std;
long long lose[1000004],win[1000004],use[1004];
long long dp[1004][1004];
int main()
{
int n,x;
cin>>n>>x;
for(int i=1;i<=n;i++)
{
cin>>lose[i]>>win[i]>>use[i];
}
for(int i=1;i<=n;i++)
for(int j=x;j>=0;j--)
{
if(j>=use[i])
dp[i][j]=max(win[i]+dp[i-1][j-use[i]],dp[i-1][j]+lose[i]);
else
{
dp[i][j]=dp[i-1][j]+lose[i];
}
}
cout<<dp[n][x]*5;
return 0;
}
题目描述
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是≤50000 的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入格式
1行,若干个整数(个数≤100000 )
输出格式
2行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入输出样例
输入
389 207 155 300 299 170 158 65
输出
6
2
第一问求一个最长不上升序列的长度 第二问求一个最长上升序列的长度
题解
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n = 0, a[100044], d1[100044], d2[100044];
int main()
{
while(cin>>a[++n]);
n--;
int len1=1,len2=1;
d1[1]=a[1];
d2[1]=a[1];
for(int i=2;i<=n;i++)
{
if(d1[len1]>=a[i])
d1[++len1]=a[i];
else
{
int p=upper_bound(d1+1,d1+1+len1,a[i],greater<int>())-d1; **数组d1 在1~len1的范围内找第一个比a[i]小的数**
d1[p]=a[i];
}
if(d2[len2]<a[i])
d2[++len2]=a[i];
else
{
int p1=lower_bound(d2+1,d2+1+len2,a[i])-d2; **数组d2 在1~len2的范围内找第一个大于等于a[i]的数**
d2[p1]=a[i];
}
}
cout<<len1<<endl<<len2;
return 0;
}
洛谷大佬的讲解 https://www.luogu.com.cn/blog/w1049/solution-p1020


浙公网安备 33010602011771号