被鸽了的文件清除
链接:https://ac.nowcoder.com/acm/contest/1091/D
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
众所周知,你整天浏览一些网站有时候因为你手贱,有些奇奇怪怪的东西不知不觉开始下载, 而你一般会立刻点掉他们, 但是却因为你很懒没有把残留文件删掉
众所周知,时间久了,因为没有删掉残留文件你手机的内存会越来越少。
现在你的手机内存已经枯竭, 你要去外太空找新能源(走错了)
现在你要开始清除残留的n个文件。
清除的方式有2种:
1.手动删除;
2.软件删除
但是你很懒,你今天至多手动删除x个文件。
手动删除必须满足上一次是软件删除,而软件删除没有要求。
第i个文件,手动删除扩充aia_iai单位的内存,软件删除扩充bib_ibi单位的内存
现在你想知道你今天最多扩出多少内存来
众所周知,时间久了,因为没有删掉残留文件你手机的内存会越来越少。
现在你的手机内存已经枯竭, 你要去外太空找新能源(走错了)
现在你要开始清除残留的n个文件。
清除的方式有2种:
1.手动删除;
2.软件删除
但是你很懒,你今天至多手动删除x个文件。
手动删除必须满足上一次是软件删除,而软件删除没有要求。
第i个文件,手动删除扩充aia_iai单位的内存,软件删除扩充bib_ibi单位的内存
现在你想知道你今天最多扩出多少内存来
输入描述:
一行一个整数n,x 表示一共有n个文件,至多手动删x个文件
接下来n行,每行两个整数a,b 表示手动删除扩充a单位的内存,软件删除扩充b单位的内存
输出描述:
一行一个整数表示最多扩充多少内存
示例1
备注:
对于30%30\%30%的数据,满足1≤n,x≤101\leq n,x\leq101≤n,x≤10
对于另外30%30\%30%的数据,满足1≤n≤105,x=01\leq n\leq 10^5,x = 01≤n≤105,x=0
对于100%100\%100%的数据,满足1≤ai,bi≤1091\leq a_i,b_i\leq10^91≤ai,bi≤109
对于100%100\%100%的数据,满足1≤n≤105,1≤x≤min{n,103}1\leq n\leq10^5,1\leq x\leq\min\{n,10^3\}1≤n≤105,1≤x≤min{n,103}
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e5+10; int n,x; ll s[maxn],t[maxn]; ll dp[3][maxn][3]; int main() { scanf("%d%d",&n,&x); for(register int i=1;i<=n;++i){ scanf("%lld%lld",&s[i],&t[i]); } for(register int i=1;i<=n;++i){ dp[i&1][0][0]=dp[(i-1)&1][0][0]+t[i]; for(register int j=1;j<=min(x,i-1);++j){ dp[i&1][j][0]=max(dp[(i-1)&1][j][0],dp[(i-1)&1][j][1])+t[i]; dp[(i&1)][j][1]=dp[(i-1)&1][j-1][0]+s[i]; } } ll res=0; for(register int i=0;i<=x;++i){ res=max(res,dp[n&1][i][0]); res=max(res,dp[(n&1)][i][1]); } printf("%lld\n",res); return 0; }