我真的是菜的一笔
T1:
一道贪心大水题,然后我wa了。。。
就是把它按照结束时间排个序,然后乱搞一下就行了
#include <cstdio>
#include <cstdlib>
#include <algorithm>
int n,ans;
struct Node{int t,s,k;} r[100005];
bool cmp(Node x,Node y){if(x.s!=y.s) return x.s<y.s;return x.k<y.k;}
int main(){
// freopen("manage.in","r",stdin);
// freopen("manage.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&r[i].t,&r[i].s),r[i].k=r[i].s-r[i].t;
std::sort(r+1,r+1+n,cmp);
ans=0;
int mn=0x3f3f3f3f;
for(int i=1;i<=n;i++){
ans+=r[i].t;
if(ans>r[i].s) {puts("-1");return 0;}
mn=std::min(mn,r[i].s-ans);
}
if(mn<0) puts("-1");
}
T2
缩点+树形背包,缩完点就和选课一样了。
tarjan写挫,dp写挫。
口胡AC,手写10分GG
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cstring>
const int N = 105;
using namespace std;
vector<int>G[N];
int n,dfn[N],tim,low[N],stk[N],top,id[N],cnt,v[N],w[N],head[N],ecnt,eecnt,hd[N],m;
bool vis[N];
struct Node {
int w,v;
} s[N];
struct Edge {
int to,nxt;
} e[N<<1];
void add(int bg,int ed) {
e[++ecnt].nxt=head[bg];
e[ecnt].to=ed;
head[bg]=ecnt;
}
void tarjan(int x) {
low[x]=dfn[x]=++tim;
stk[++top]=x;
vis[x]=1;
for(int i=head[x],u; i; i=e[i].nxt) {
u=e[i].to;
if(!dfn[u]) {
tarjan(u);
low[x]=std::min(low[x],low[u]);
} else if(vis[u]) low[x]=std::min(low[x],dfn[u]);
}
if(dfn[x]==low[x]) {
int k;
++cnt;
do {
k=stk[top--];
vis[k]=0;
id[k]=cnt;
s[cnt].v+=v[k],s[cnt].w+=w[k];
} while(k!=x);
}
}
int f[N][N*5],ru[N];
void dp(int x){
if(s[x].w>m)return;
memset(f[x],0xcf,sizeof f[x]);
for(int i=s[x].w;i<=m;i++) f[x][i]=s[x].v;
for(int i=0;i<G[x].size();i++) {
dp(G[x][i]);
for(int j=m;j>=s[x].w;j--) {
for(int k=j;k>=0;k--) {
f[x][j]=max(f[x][j-k]+f[G[x][i]][k],f[x][j]);
}
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1,x; i<=n; i++)
scanf("%d",&w[i]);
for(int i=1,x; i<=n; i++)
scanf("%d",&v[i]);
for(int i=1,x; i<=n; i++)
{ scanf("%d",&x);if(x)add(x,i);}
for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++) {
for(int j=head[i];j;j=e[j].nxt) {
int v=e[j].to;
if(id[v]!=id[i]){
G[id[i]].push_back(id[v]);
ru[id[v]]++;
}
}
}
for(int i=1;i<=cnt;i++)
if(!ru[i]){
dp(i);
for(int j=m;j>=0;j--){
for(int k=j;k>=0;k--){
f[0][j]=max(f[0][j],f[i][k]+f[0][j-k]);
}
}
}
printf("%d",f[0][m]);
}
T3
一道线段树的操作题。也可以分块ryc分块写挫
线段树维护最长连续上升子序列裸题,写挂交暴力。
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using std::max;
const int N=1e6;
struct Seg{
int l,r,len;double mx;
}t[N<<2];
void build(int l,int r,int cur){
t[cur].l=l;t[cur].r=r;
if(l==r){return;}
int mid=(l+r)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
}
int query(int cur,double hig) {
if(t[cur].l==t[cur].r)return t[cur].mx>hig;
if(t[cur<<1].mx>=hig) return t[cur].len-t[cur<<1].len+query(cur<<1,hig);
else return query(cur<<1|1,hig);
}
void update(int cur,double hig,int now){
if(t[cur].l==t[cur].r) {t[cur].mx=hig,t[cur].len=1;return;}
int mid=(t[cur].l+t[cur].r)>>1;
if(mid>=now) update(cur<<1,hig,now);
else update(cur<<1|1,hig,now);
t[cur].mx=max(t[cur<<1].mx,t[cur<<1|1].mx);
t[cur].len=t[cur<<1].len+query(cur<<1|1,t[cur<<1].mx);
}
int main(){
int n,m,x,y;
scanf("%d%d%",&n,&m);
build(1,n,1);
while(m--){
scanf("%d%d",&x,&y);
update(1,(double)y/(double)x,x);
printf("%d\n",t[1].len);
}
}
总结:我太菜了,GhostCai不可能把我按在键盘上 !a~ 阿QASA发挥得犯的话题
重来:我太菜了,平时写题细节上挂了就看题解,导致代码查错很菜啊,还有树上的东西好像一直掌握的不太扎实网络流大法好!
原文地址:https://www.cnblogs.com/sdfzhsz/p/9259730.html
时间: 2024-11-08 16:25:49