9.1 联合作战战果

1.处理内容:

树链剖分4题

最大流模板1题

线性DP3题

bellman-ford判负环1题


2.树剖

直接甩链接

3.最大流模板 略过

4.线性DP

水题1:目测是USACO2009Open的滑雪课

f[i][j]为i时能力j的最大滑雪次数

第一种转移:我什么都不做这是坠吼的——用f[i][j]更新f[i+1][j]

第二种转移:上课,当然是当前时间且值更高——用f[i][j]更新f[i+l][a]

第三种转移:滑雪,当前能力最大值,稍微要点预处理——用f[i][j]+1更新f[i+d][j]

局部完结撒花

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<1)+(i<<3)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
#define stan1 111
#define stan2 11111
int t,s,n,m,l,a,x,y,nxt[stan1],first[stan2],tme[stan1],val[stan1],bst[stan1],f[stan2][stan1],ans;
signed main(){
	t=read();s=read();n=read();
	for(int i=1;i<=s;++i){
		m=read();tme[i]=read();val[i]=read();
		nxt[i]=first[m];
		first[m]=i;
	}
	for(int i=1;i<=100;++i) bst[i]=999999;
	for(int i=1;i<=n;++i){
		x=read();y=read();
		if(bst[x]>y) bst[x]=y;
	}
	for(int i=1;i<100;++i)
		if(bst[i]<bst[i+1])
			bst[i+1]=bst[i];
	memset(f,128,sizeof(f));
	f[0][1]=0;
	for(int i=0;i<t;++i)
		for(int j=1;j<=100;++j)
			if(f[i][j]>=0){
				if(f[i+1][j]<f[i][j])
					f[i+1][j]=f[i][j];
				if(i+bst[j]<=t)
					f[i+bst[j]][j]=max(f[i+bst[j]][j],f[i][j]+1);
				for(int p=first[i];p;p=nxt[p]){
					if(i+tme[p]<=t&&val[p]>j)
						f[i+tme[p]][val[p]]=max(f[i+tme[p]][val[p]],f[i][j]);
				}
			}
	for(int j=1;j<=100;++j)
		if(f[t][j]>ans)
			ans=f[t][j];
	write(ans);
	return 0;
}
水题2:Bbj

A 和 B 玩游戏。每回合,每个人需要作出下列决策之一:

1. 充能:增加一点能量值

2. 攻击:消耗一点能量值,攻击对方

3. 防御:可以抵挡对方的攻击

两个人同时攻击时视作抵消。某人被攻击时若在充能则该人输去。一开始每个人的能量均为零。已知游戏经过了 n 回合后仍未分出胜负,求有多少种可能的游戏

局面。答案模 1e9 + 7。

因为n<=200 所以你用dfs直接爆搜肯定药丸

定义f[x][y][z]表示x回合甲能量为y乙能量为z

然后n^3再次局部完结撒花

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define mod 1000000007
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<1)+(i<<3)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(long long x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
int n,f[222][222][222];
int dfs(int x,int y,int z){
	if(y<0||z<0) return 0;
	if(x>n) return 1; 
	if(f[x][y][z]!=-1) return f[x][y][z];
	f[x][y][z]=0;
	for(int i=-1;i<=1;++i)
		for(int j=-1;j<=1;++j)
			if((i==1&&j==-1)||(j==1&&i==-1)) continue;
			else 
				f[x][y][z]=(f[x][y][z]+dfs(x+1,y+i,z+j))%mod;
	return f[x][y][z];
}
signed main(){
	memset(f,-1,sizeof(f));
	n=read();
	write(dfs(1,0,0));
	return 0;
}
难题:地精部落

容我想想,卒

临死决定甩个链接

http://blog.csdn.net/mrazer/article/details/53426415?locationNum=12&fps=1

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<1)+(i<<3)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
int n,p,f[2][5555];
signed main(){
	n=read();p=read();
	f[1][1]=1;
	for(int i=2;i<=n;++i)
		for(int j=1;j<=i;++j)
			f[i&1][j]=(f[i&1][j-1]+f[(i&1)^1][i-j])%p;
	write((f[n&1][n]<<1)%p);
	return 0;
}

4.bellman-ford 略

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
	int i=0,f=1;
	char ch;
	for(ch=getchar();!isdigit(ch);ch=getchar())
		if(ch=='-') f=-1;
	for(;isdigit(ch);ch=getchar())
		i=(i<<1)+(i<<3)+(ch^48);
	return i*f;
}
int buf[1024];
inline void write(int x){
	if(!x){putchar('0');return ;}
	if(x<0){putchar('-');x=-x;}
	while(x){buf[++buf[0]]=x%10,x/=10;}
	while(buf[0]) putchar(buf[buf[0]--]+48);
	return ;
}
int x,cnt[555],tot,n,m,w,s,e,t,to[555],from[5555],first[555],nxt[5555],goal[5555],dis[5555],exi[555];
void addedge(int a,int b,int c){
	++tot;nxt[tot]=first[a];first[a]=tot;from[tot]=a;goal[tot]=b;dis[tot]=c;
	return ;
}
bool check(){
	
	for(int i=2;i<=n;++i)
		to[i]=999999999;
	for(int i=1;i<n;++i){
		int tag=0;
		for(int p=1;p<=tot;++p)
			if(to[goal[p]]>to[from[p]]+dis[p]){
				to[goal[p]]=to[from[p]]+dis[p];
				tag=1;
			}
		if(!tag) break;
	}
	for(int p=1;p<=tot;++p)
		if(to[goal[p]]>to[from[p]]+dis[p])
			return true;
		return false;
}
signed main(){
	x=read();
	while(x--){
		tot=0;
		memset(cnt,0,sizeof(cnt));
		memset(first,0,sizeof(first));
		n=read();m=read();w=read();
		for(int i=1;i<=m;++i){
			s=read();e=read();t=read();
			addedge(s,e,t);
			addedge(e,s,t);
		}
		for(int i=1;i<=w;++i){
			s=read();e=read();t=read();
			addedge(s,e,-1*t);
		}
		if(check()) puts("YES");
		else puts("NO");
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值