2018.7.19模拟赛

盲人oi,the best oi
T1:
DP+贪心
贪心地让以i为结尾的序列的最后一段最小,直接转移。

#include <bits/stdc++.h>
const int N=200005;
long long n,h[N],f[N],sum[N],las[N];
int main(){
	freopen("tower.in","r",stdin);
	freopen("tower.out","w",stdout);
	std::cin>>n;
	for(int i=1;i<=n;i++) std::cin>>h[i],sum[i]=sum[i-1]+h[i];
	f[1]=1;las[1]=h[1];f[0]=0;
	for(int i=2;i<=n;i++) 
		for(int j=i-1;~j;j--) 
			if(sum[i]-sum[j]>=las[j]) {f[i]=f[j]+1;las[i]=sum[i]-sum[j];break;}
	std::cout<<n-f[n];
}

T2:
简单DP,分类讨论即可。
数组开小100倍海星,改了直接A。。。。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct CLASS{int k,c;}w[10005];
int t,s,n,g[10005],f[10005][105],a[105];
int main() {
	freopen("wrk.in","r",stdin);
	freopen("wrk.out","w",stdout);
	memset(a,0x3f,sizeof a);
	scanf("%d%d%d",&t,&s,&n);
	for(int i=1,tt,e;i<=s;i++) 
	scanf("%d%d",&tt,&e),scanf("%d",&w[tt+e].c),w[tt+e].k=e;
	for(int i=1,tt,r;i<=n;i++) 
	scanf("%d%d",&tt,&r),a[tt]=min(a[tt],r);
	for(int i=1;i<=100;i++) a[i]=min(a[i],a[i-1]);
	memset(f,0xcf,sizeof f);
	f[0][1]=0;
	for(int i=1;i<=t;i++) {
		for(int j=1;j<=100;j++) f[i][j]=f[i-1][j];
		for(int j=100;j&&a[j]<=i;j--) {
			f[i][j]=max(f[i][j],f[i-a[j]][j]+1);
		}
		if(w[i].k) 
		for(int j=1;j<w[i].c;j++)f[i][w[i].c]=max(f[i-w[i].k][j],f[i][w[i].c]);
	}
	int ans=0;
	for(int i=1;i<=100;i++) ans=max(ans,f[t][i]);
	cout<<ans;
}

T3
题解参见Candy?
https://www.cnblogs.com/candy99/p/6003565.html

#include <bits/stdc++.h>
using namespace std;
const int N=2005,inf=0x3f3f3f3f;
int n,m,k,head[N],ecnt,du[N],dis[N],len,rt;
struct Edge {int to,nxt;} e[N*N<<1];
void add(int bg,int ed) {e[++ecnt].nxt=head[bg];e[ecnt].to=ed;head[bg]=ecnt;}
bool vis[N];
void dfs(int x) {vis[x]=1,len++;for(int i=head[x]; i; i=e[i].nxt) {int v=e[i].to;if(!vis[v]) dfs(v);}}
void bfs(int x) {
	queue<int>q;q.push(x);
	memset(dis,-1,sizeof dis);dis[x]=0;
	while(!q.empty()) {
		int u=q.front();q.pop();
		for(int i=head[u]; i; i=e[i].nxt) {
			int v=e[i].to;
			if(dis[v]==-1) {dis[v]=dis[u]+1;q.push(v);}
		}
	}
}
bool ck(int dist) {
	int ans=inf;
	for(int x=1; x<=n; x++) {
		bfs(x);
		if(dis[rt]>dist) continue;
		int cnt=0;
		memset(vis,0,sizeof vis);
		for(int i=1; i<=n; i++) if(dis[i]<=dist) vis[i]=1;
		for(int i=1; i<=n; i++)
			if(!vis[i]) {len=0;dfs(i);cnt+=(len-1)/(2*dist+1)+1;}
			ans=min(ans,cnt+1);
	}
	return ans<=k;
}
int main() {
	freopen("holes.in","r",stdin);
	freopen("holes.out","w",stdout);
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1,u,v; i<=m; i++) {scanf("%d%d",&u,&v);add(u,v);add(v,u);du[u]++,du[v]++;}
	for(int i=1; i<=n; i++) if(du[i]>3) {rt=i;break;}
	if(!rt) return !printf("%d
",(n+k-1)/(2*k));
	int l=1,r=n,ans=inf;
	while(l<=r) {
		int mid=l+r>>1;
		if(ck(mid)) r=mid-1,ans=min(ans,mid);
		else l=mid+1;
	}
	cout<<ans;
}
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9336491.html