周四做了一下dp专题的题目,但好像都不是dp,因为直接做会超时。d题用的以前见过的一种二分思想,求最长上升子序列,前后各求一遍,然后o(n)遍历求解。还有一个卡特兰数的题目,这个题目其实自己并不知道,听到是卡特兰,打表一下就看出来了。
周五晚上的比赛,a题贪心,但是好像用set做会出问题,改成优先队列就行了
ac代码:
#include<cmath>
#include<cstring>#include<algoritm>
#include<cstdio>
using namespace std;
const int maxn=200010;
const int mo=1e9+7;
int c[maxn],aa[maxn];
int ans,cnt,tmp;
int b[maxn],flag;
struct node{
int num;
int w;
bool operator<(node a)const{
return num>a.num;
}
}a[maxn];
double p,q;
int main(){
int T,cas,n,m;
while(scanf("%d %d",&n,&m)!=EOF){
priority_queue<int,vector<int>,greater<int> >q;
ans=0;
flag=0;
for(int i=0;i<n;i++){
scanf("%d",&c[i]);
}
sort(c,c+n);
for(int i=0;i<m;i++){
scanf("%d %d",&a[i].num,&a[i].w);
}
sort(a,a+m);
int j=n-1;
int i=0;
flag=1;
ll ans=0;
for(int j=n-1;j>=0;j--){
while(i<m&&a[i].num>=c[j]){
q.push(a[i].w);
i++;
}
if(q.empty()){flag=0;break;}
int tmp=q.top(); q.pop();
ans+=(ll)tmp;
}
if(flag) printf("%lld\n",ans);
else puts("-1");
}
return 0;
}。
b题一个模拟,模拟坐车的所有情况即可。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 10010
using namespace std;
long long vis[6];
int main(){
long long m,n,l,i,j,xx,yy;
while (scanf("%lld",&n)!=EOF){
memset (vis,0,sizeof(vis));
for (i=1;i<=n;i++){
scanf("%lld",&xx);
vis[xx]++;
}
long long ans=vis[5];
ans+=vis[4];
if (vis[4]>vis[1]){
vis[1]=0;
}
else {
vis[1]-=vis[4];
}
ans+=vis[3];
if (vis[3]>vis[2]){
vis[3]-=vis[2];
vis[2]=0;
if (2*vis[3]<vis[1]){
vis[1]-=2*vis[3];
double cc=vis[1];
ans+=ceil(cc/5.0);
}
}
else {
vis[2]-=vis[3];
if (vis[2]%2==0){
ans+=vis[2]/2;
if (vis[2]/2<vis[1]){
vis[1]-=vis[2]/2;
double cc=vis[1];
ans+=ceil(cc/5.0);
}
}
else {
ans+=vis[2]/2+1;
if (vis[2]/2+3<vis[1]){
vis[1]-=vis[2]/2+3;
double cc=vis[1];
ans+=ceil(cc/5.0);
}
}
}
cout<<ans<<endl;
}
}
c题公式或者奇偶模拟,判断最后一个数出去没有,或者直接公式,我的模拟似乎出了点问题,过了百分之八十,有点迷。
公式就是n/2到n是偶数,每次加(x+1)/2,最后加x+1。
周六去济南拆线了,说的是植入色素成功了,再过一段时间就不用去济南了,困扰了我多年的遗传病。。。