dp 系列专题(三)

4 篇文章 0 订阅
3 篇文章 0 订阅

LA 4945

#define LIM 1010
struct node{
	int pi,ji;
   	friend bool operator < (const node&a,const node&b)  {
   		if( a.ji == b.ji ){
   			return a.pi<b.pi;
   		}
   		return a.ji>b.ji;
   	}
};
node a[LIM];
int n;
bool cmp(const node&ta,const node&tb){
	if( ta.pi == tb.pi ){
		return ta.ji<tb.ji;
	}
	return ta.pi > tb.pi;
}
priority_queue<node> PQ;
int main() {
	int T;
	cin >> T;
	string s;
	while (T--) {
		cin >> n;
		cin >> s;
		for (int i = 0; i < n; ++i) {
			cin >> a[i].pi >> a[i].ji;
		}
		sort(a, a + n, cmp);
		int pet=0,jan=0;
		int petstart=(s[0]=='P');
		if( petstart ){
			pet+=a[0].pi;
		}
		for(int i=petstart;i<n;i+=2){
			PQ.push(a[i]);
			if( i+1 < n ){
				PQ.push(a[i+1]);
				int t=PQ.top().pi;
				PQ.pop();
				pet+=t;
			}
		}
		while( !PQ.empty() ){
			jan+=PQ.top().ji;
			PQ.pop();
		}
		cout<<pet<<" "<<jan<<endl;
	}
	return 0;
}

LA 4015

#define LIM 510
int Head[LIM];
struct node{
	int v,w,next;
};
node e[LIM*2];int alloc;
void addedge(int u,int v,int w){
	e[alloc].w=w;e[alloc].v=v;e[alloc].next=Head[u];
	Head[u]=alloc++;
}
/**************************************************************************************/
int N;
int go[LIM][LIM];
int back[LIM][LIM];
int sz[LIM];
int In[LIM];
void init(){
	alloc=0;memset(Head,-1,sizeof(Head));
	for(int i=0;i<=N;++i){
		for(int j=0;j<=N;++j){
			go[i][j]=back[i][j]=INF;
		}
	}
}
void dfs(int u,int pre){
	go[u][1]=0;back[u][1]=0;sz[u]=1;
	for(int t=Head[u]; t!=-1 ; t=e[t].next){
		int v=e[t].v;
		if( v!=pre ){
			dfs(v,u);sz[u]+=sz[v];
			for (int i = sz[u]; i >= 2; --i) {
				for (int j = 1; j <= sz[v] && i - j >= 1; ++j) {
					if ((go[u][i - j] != INF && back[v][j] != INF)
							|| (back[u][i - j] != INF && go[v][j] != INF)) {
						go[u][i] = min(go[u][i],
								go[u][i - j] + back[v][j] + e[t].w * 2,
								back[u][i - j] + go[v][j] + e[t].w);
					}
					if (back[u][i - j] != INF && back[v][j] != INF) {
						back[u][i] = min(back[u][i],
								back[u][i - j] + back[v][j] + e[t].w * 2);
					}
				}
			}
		}
	}
}
int main()
{
	int x,y,z;
	int cnt=1;
    while( scanf("%d",&N) != EOF ){
    	if( N==0 ) break;
    	init();
    	for(int i=1;i<N;++i){
    		scanf("%d%d%d",&x,&y,&z);
    		addedge(y,x,z);In[x]++;
    	}
    	int root=0;
    	for(int i=0;i<N;++i){
    		if( In[i] == 0 ){
    			root=i;break;
    		}
    	}
    	dfs(root,-1);
    	printf("Case %d:\n",cnt++);
    	int Q;
    	scanf("%d",&Q);
    	while( Q-- ){
    		scanf("%d",&x);
    		for(int i=N;i>=0;--i){
    			if( x >= min(go[root][i],back[root][i]) ){
    				printf("%d\n",i);
    				break;
    			}
    		}
    	}
    }
    return 0;
}

LA 4490
#define LIM 110
#define MAXN (1<<8)
int a[LIM];
int d[LIM][LIM][10][MAXN+10];
int main()
{
	int N,K;
	int cnt=1;
	while( cin>>N>>K ){
		if( N==0 && K==0) break;
		int Allstate=0;
		for(int i=1;i<=N;++i){
			cin>>a[i];
			a[i]-=25;
			Allstate|=(1<<a[i]);
		}
		memset(d,127,sizeof(d));
		d[0][0][8][0]=0;
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j <= min(i, K); ++j) {
				for (int k = 0; k <= 8; ++k) {
					for (int s = 0; s < MAXN; ++s) {
						if (d[i][j][k][s] <= N) {
							if (a[i + 1] == k) {
								d[i + 1][j][k][s] = min(d[i + 1][j][k][s],
										d[i][j][k][s]);
							} else {
								d[i + 1][j][a[i + 1]][s | (1 << a[i + 1])] =
										min(
												d[i + 1][j][a[i + 1]][s
														| (1 << a[i + 1])],
												d[i][j][k][s] + 1);
							}
							if (j < K)
								d[i + 1][j + 1][k][s] = min(
										d[i + 1][j + 1][k][s], d[i][j][k][s]);
						}
//						if( i==0 )
//						cout<<"d["<<i<<"]["<<j<<"]["<<k<<"]["<<s<<"] "<<d[i][j][k][s]<<endl;
					}
				}
			}
		}
		int ans=INF;
		for (int h = 0; h <= K; ++h) {
			for (int j = 0; j < MAXN; ++j) {
				for (int i = 0; i < 8; ++i) {
					if (d[N][h][i][j] > N)
						continue;
					int t = d[N][h][i][j];
					for (int k = 0; k < 8; ++k) {
						if ((Allstate & (1 << k)) && !(j & (1 << k))) {
							t++;
						}
					}
//				cout<<"d["<<N<<"]["<<K<<"]["<<i<<"]["<<j<<"] "<<d[N][K][i][j]<<endl;
//				cout<<"t "<<t<<endl;
					ans = min(ans, t);
				}
			}
		}
		cout<<"Case "<<cnt++<<": "<<ans<<endl<<endl;
	}
	return 0;
}

uva 11660

#define LIM 35
int parent[LIM];
int S[LIM];
void init(){
	memset(parent,-1,sizeof(parent));
}
int Find(int u){
	return parent[u]==-1?u:parent[u]=Find(parent[u]);
}
void Union(int u,int v){
	int r1=Find(u),r2=Find(v);
	if( r1!=r2 ){
		if( r1 ==1 ){
			parent[r2]=r1;
			S[r1]+=S[r2];
		}
		else{
			parent[r1]=r2;
			S[r2]+=S[r1];
		}
	}
}
/**************************************************************************************/
struct node{
	int num;
	int cur;
	int a[35];
	node(){ num=0; }
	bool operator < (const node&t )const {
		if( cur == t.cur ){
			for(int i=0;i<num;++i){
				if( a[i] != t.a[i] ){
					return a[i]<t.a[i];
				}
			}
			return false;
		}
		return cur<t.cur;
	}
};
map<node,double> Map;
int N,M;
double dfs(node x){
	if( x.num == 0 ) return 0;
	if( Map.count(x) ){
		return Map[x];
	}
	node tmp;
	double ans=0.0;
	for(int i=0;i<x.num;++i){
		tmp=x;
		tmp.cur=x.cur+x.a[i];
		tmp.num=x.num-1;
		for(int j=i+1;j<x.num;++j){
			tmp.a[j-1]=x.a[j];
		}
//		sort(tmp.a,tmp.a+tmp.num);
		ans += dfs(tmp)*x.a[i];
	}
	ans += N-1;
	ans /= (N-x.cur);
	return Map[x]=ans;
}
int main()
{
	int T;
	scanf("%d",&T);
	int cnt=1;
	while( T-- ){
		init();
		Map.clear();
		scanf("%d%d",&N,&M);
		for(int i=1;i<=N;++i) S[i]=1;
		int x,y;
		for(int i=0;i<M;++i){
			scanf("%d%d",&x,&y);
			Union(x,y);
		}
		node tmp;
		tmp.cur=S[1];
		for(int i=2;i<=N;++i){
			if( parent[i]==-1 ){
				tmp.a[tmp.num++]=S[i];
			}
		}
		sort(tmp.a,tmp.a+tmp.num);
//		cout<<"tmp.cur "<<tmp.cur<<endl;
//		cout<<"tmp.a "<<endl;
//		for(int i=0;i<tmp.num;++i){
//			cout<<"i "<<tmp.a[i]<<endl;
//		}
		printf("Case %d: %.6lf\n",cnt++,dfs(tmp));
	}
    return 0;
}

LA 4987 目测oj数据有点问题

我的代码(后来下了官方数据,对比了一下,好像是对的,而且这题应该要spj的)

#define LIM 4010
struct node{
	int id,value;
	bool operator < (const node &x)const {
		return value < x.value;
	}
};
node a[LIM];
node b[LIM];
i64 d[LIM][LIM];
int p[LIM][LIM];
int z[LIM][LIM];
int Rec[LIM];
int bin1(int s,int e,int x){
	int t,step;
	int count=e-s;
	while( count>0 ){
		t=s;step=count/2;t+=step;
		if( b[t].value < x ){
			s=++t; count-=step+1;
		}
		else count=step;
	}
	return s;
}
int bin2(int s,int e,int x){
	int t,step;
	int count=e-s;
	e--;
	while( count>0 ){
		t=e;step=count/2;t-=step;
		if( b[t].value > x ){
			e=--t;count-=step+1;
		}
		else count=step;
	}
	return e;
}
void dfs(int x,int y){
	if( x==0 ) return ;
	dfs(x-1,p[x][y]);
	Rec[a[x].id]=b[z[x][y]].id;
}
int main()
{
//	freopen("64.txt","r",stdin);
//	freopen("out64.txt","w",stdout);
	int N,M;
	while( scanf("%d",&N)!=EOF ){
		for(int i=1;i<=N;++i){
			scanf("%d",&a[i].value);
			a[i].id=i;
		}
		scanf("%d",&M);
		for(int i=1;i<=M;++i){
			scanf("%d",&b[i].value);
			b[i].id=i;
		}
		sort(a+1,a+N+1);
		sort(b+1,b+M+1);
		for(int i=0;i<=N;++i){
			for(int j=0;j<=M;++j){
				d[i][j]=INF;
			}
		}
		d[0][0]=0;
		for(int i=1;i<=N;++i){
			for(int j=1;j<=i && j<=M;++j){
				if( d[i-1][j-1]+Abs(a[i].value-b[j].value) < d[i][j] ){
					d[i][j]=d[i-1][j-1]+Abs(a[i].value-b[j].value);
					p[i][j]=j-1;
					z[i][j]=j;
				}
				int t1=bin1(1,j+1,a[i].value);
//				cout<<endl;
//				cout<<"i "<<i<<" j "<<j<<endl;
//				cout<<"t1 "<<t1<<endl;
				if( t1 != j+1 && d[i-1][j]+Abs(a[i].value-b[t1].value) < d[i][j] ){
					d[i][j]=d[i-1][j]+Abs(a[i].value-b[t1].value);
					p[i][j]=j;
					z[i][j]=t1;
				}
				t1=bin2(1,j+1,a[i].value);
//				cout<<"t2 "<<t1<<endl;
				if( t1 != 0 &&  d[i-1][j]+Abs(a[i].value-b[t1].value) < d[i][j] ){
					d[i][j]=d[i-1][j]+Abs(a[i].value-b[t1].value);
					p[i][j]=j;
					z[i][j]=t1;
				}
			}
		}
//		for(int i=1;i<=N;++i){
//			for(int j=1;j<=M;++j){
//				cout<<endl<<"d["<<i<<"]["<<j<<"] "<<d[i][j]<<endl;
//				cout<<"p["<<i<<"]["<<j<<"] "<<p[i][j]<<endl;
//				cout<<"z["<<i<<"]["<<j<<"] "<<z[i][j]<<endl;
//			}
//		}
		printf("%I64d\n",d[N][M]);
		dfs(N,M);
		printf("%d",Rec[1]);
		for(int i=2;i<=N;++i){
			printf(" %d",Rec[i]);
		}
		printf("\n");
	}
	return 0;
}


LA 4593(完全看了标程写的)

int N;
#define LIM 16
bool edge[LIM][LIM];
int process[110][2];
bool NotInclude[1<<LIM];
int dp[1<<LIM];
int pre[1<<LIM];
int color[LIM];
map<char,int> M;
char hash[LIM];
int main()
{
	char str1[10],str2[10];
	while( scanf("%d",&N) != EOF ){
		memset(edge,false,sizeof(edge));
		memset(NotInclude,false,sizeof(NotInclude));
		M.clear();
		int Index=0;
		for(int i=0;i<N;++i){
			scanf("%s%s",str1,str2);
			if( !M.count(str1[0]) ){
				M[str1[0]]=Index;
				hash[Index]=str1[0];
				Index++;
			}
			if( !M.count(str2[0]) ){
				M[str2[0]]=Index;
				hash[Index]=str2[0];
				Index++;
			}
			process[i][0]=M[str1[0]];
			process[i][1]=M[str2[0]];
			edge[process[i][0]][process[i][1]]=true;
			edge[process[i][1]][process[i][0]]=true;
		}
		int size=Index;
//		cout<<"size "<<size<<endl;
		int ALL=(1<<size);
		for(int i=0;i<ALL;++i){
			NotInclude[i]=true;
			bool flag=false;
			for(int j=0;j<N;++j){
				int t=((1<<process[j][0]) | (1<<process[j][1]));
				if( ( (i|t) == i ) ){
					flag=true;
					break;
				}
			}
			if( flag ){
				NotInclude[i]=false;
			}
		}
		memset(dp,127,sizeof(dp));
//		if( dp[0] == INF ) cout<<"Yes "<<endl;
		dp[0]=0;
		int Fullstate=ALL-1;
		for(int i=0;i<ALL;++i){
			if( dp[i] == INF ) continue;
			int cur=Fullstate&(~i);
			for(int subset=cur; subset > 0 ; subset=cur&(subset-1)){
				int newstate= i | subset;
				if( NotInclude[subset] ){
					if( dp[newstate] > dp[i] + 1 ){
//						cout<<"debug "<<endl;
//						cout<<"dp["<<i<<"] "<<dp[i]<<endl;
//						cout<<"dp["<<newstate<<"] "<<dp[newstate]<<endl;
						dp[newstate]=dp[i]+1;
						pre[newstate]=i;
					}
				}
			}
//			cout<<"dp["<<i<<"] "<<dp[i]<<endl;
		}
//		for(int i=0;i<ALL;++i){
//			cout<<"dp["<<i<<"] "<<dp[i]<<endl;
//		}
		int curstate=Fullstate;
		int curentcolor=dp[Fullstate];
		while( curstate>0 ){
			int prestate=pre[curstate];
			int dif=curstate&(~prestate);
			for(int i=0;i<size;++i){
				if( dif&(1<<i) ){
					color[i]=curentcolor;
				}
			}
			curstate=prestate;
			curentcolor--;
		}
		printf("%d\n",dp[Fullstate]-2);
		for(int i=0;i<N;++i){
			if( color[process[i][0]] < color[process[i][1]] ){
				printf("%c %c\n",hash[process[i][0]],hash[process[i][1]]);
			}
			else{
				printf("%c %c\n",hash[process[i][1]],hash[process[i][0]]);
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值