160104 HAOI2013 总结

T1

正着跑一边多重,反着跑一遍多重背包,然后枚举干掉的那个玩偶左边和右边的钱数

考场上觉得会T。。卡了好久常数结果发现他数据水爆了 100

T2

设dp[I]表示当前点黑色要赢必须拿下几个子叶子节点

如果当前是白色节点的决策点,dp[I]=sigma dp[son[i]]

如果当前是黑色节点的决策点,dp[I]=min{dp[son[i]]}

边界是叶子节点dp=1

考场上不小心把第一个数和第二个数输出反了。。。。100->10

T3

暴力。。。

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
using namespace std;
inline void splay(int &v){
	v=0;char c=0;int p=1;
	while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
	while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
	v*=p;
}
int dp1[1005][1005];
int dp2[1005][1005];
int a[1005],b[1005],c[1005];
int main(){
	freopen("bag.in","r",stdin);
	freopen("bag.out","w",stdout);
	int n;splay(n);
	for(int i=1;i<=n;i++){
		splay(a[i]),splay(b[i]),splay(c[i]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1000;j>=0;j--){
			for(int k=0;k<=c[i];k++){
				if(j-k*a[i]<0)break;
				int l=dp1[i-1][j-k*a[i]]+k*b[i];
				if(l>dp1[i][j])dp1[i][j]=l;
			}
		}
	}
	for(int i=n;i>=1;i--){
		for(int j=1000;j>=0;j--){
			for(int k=0;k<=c[i];k++){
				if(j-k*a[i]<0)break;
				int l=dp2[i+1][j-k*a[i]]+k*b[i];
				if(l>dp2[i][j])dp2[i][j]=l;
			}
		}
	}
	int q,lim,money;splay(q);
	for(int i=1;i<=q;i++){
		splay(lim),splay(money);
		int ans=0;lim++;
		for(int i=0;i<=money;i++){
			int p=dp1[lim-1][i]+dp2[lim+1][money-i];
			if(p>ans)ans=p;
		}
		printf("%d\n",ans);
	}
}
//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define white 0
#define black 1
#define inf 1000000000
using namespace std;
inline void splay(int &v){
	v=0;char c=0;int p=1;
	while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
	while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
	v*=p;
}
struct Edge{
	int to,next;
}edge[400010];
int first[200010],size,n;
void addedge(int x,int y){
	size++;
	edge[size].to=y;
	edge[size].next=first[x];
	first[x]=size;
}
int dp[200010];
bool isblack[200010],iswhite[200010];
bool is[200010];int col[200010];
void dfs(int now,int fa){
	col[now]=(col[fa]^1);is[fa]=false;
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to!=fa){
			dfs(edge[u].to,now);
		}
	}
}
void treedp1(int now,int fa){
	if(is[now]){dp[now]=1;return;}
	dp[now]=((col[now]==black)?inf:0);
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to==fa)continue;
		treedp1(edge[u].to,now);
		if(col[now]==black)dp[now]=min(dp[now],dp[edge[u].to]);
		if(col[now]==white)dp[now]+=dp[edge[u].to];
	}
}
void treedp2(int now,int fa){
	if(is[now]){dp[now]=1;return;}
	dp[now]=((col[now]==black)?0:inf);
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to==fa)continue;
		treedp2(edge[u].to,now);
		if(col[now]==white)dp[now]=min(dp[now],dp[edge[u].to]);
		if(col[now]==black)dp[now]+=dp[edge[u].to];
	}
}
void dfs1(int now,int fa){
	if(is[now]){isblack[now]=true;return;}
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to==fa)continue;
		if(col[now]==white)dfs1(edge[u].to,now);
		else if(dp[edge[u].to]==dp[now])dfs1(edge[u].to,now);
	}
}
void dfs2(int now,int fa){
	if(is[now]){iswhite[now]=true;return;}
	for(int u=first[now];u;u=edge[u].next){
		if(edge[u].to==fa)continue;
		if(col[now]==black)dfs2(edge[u].to,now);
		else if(dp[edge[u].to]==dp[now])dfs2(edge[u].to,now);
	}
}
void calc_black(){
	treedp1(1,0);dfs1(1,0);
}
void calc_white(){
	treedp2(1,0);dfs2(1,0);
}
int main(){
	int _q=20<<20;
	char *_p=(char*)malloc(_q)+_q;
	__asm__("movl %0, %%esp\n"::"r"(_p));
	freopen("gametree.in","r",stdin);
	freopen("gametree.out","w",stdout);
	splay(n);memset(is,true,sizeof(is));
	for(int i=2;i<=n;i++){
		int x;splay(x);
		addedge(i,x),addedge(x,i);
	}
	dfs(1,0);calc_black();calc_white();
	int ans1=0,ans2=0,ans3=0;
	for(int i=n;i>=1;i--){
		if(isblack[i]&&iswhite[i]){
			ans1++;ans2=i;ans3^=i;
		}
	}
	printf("%d %d %d\n",ans2,ans1,ans3);
}

//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#define eps 1e-7
#define E 1000000000
using namespace std;
inline void splay(int &v){
	v=0;char c=0;int p=1;
	while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
	while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
	v*=p;
}
int n,lastans,tot;
int num[100010],id[100010];double h[100010];
int main(){
	freopen("segment.in","r",stdin);
	freopen("segment.out","w",stdout);
	splay(n);while(n--){
		int opt;splay(opt);
		if(!opt){
			int x;splay(x);x=(x+lastans-1)%39989+1;
			printf("%d\n",lastans=num[x]);
		}
		else{
			int x,y,xx,yy;splay(x),splay(y),splay(xx),splay(yy);
			x=(x+lastans-1)%39989+1;y=(y+lastans-1)%1000000000+1;++tot;
			xx=(xx+lastans-1)%39989+1;yy=(yy+lastans-1)%1000000000+1;
			if(x>xx)swap(x,xx),swap(y,yy);
			double k=double(yy-y)/double(xx-x),b=double(y)-k*double(x);
			for(int j=x;j<=xx;j++){
				if(k*j+b>h[j]){
					h[j]=k*j+b,num[j]=tot;
				}
			}
		}
	}
}



你可能感兴趣的:(dp,乱搞)