zoukankan      html  css  js  c++  java
  • BZOJ2073 「POI2004」PRZ 状压DP

    问题描述

    BZOJ2073


    题解

    发现 (n le 16) ,显然想到状压

    (opt[S]) 代表过河集合为 (S) 时,最小时间。

    枚举 (S) 的子集,进行转移


    枚举子集的方法

    对于 (j)(k) 的子集

    当知道 (j)

    for(int k=(j+1)|j;k<=S;k=(k+1)|j)
    

    当知道 (k)

    for(int j=(k-1)&k;j;j=(j-1)&k)
    

    (mathrm{Code})

    #include<bits/stdc++.h>
    using namespace std;
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    	if(ch=='-') ch=getchar(),fh=-1;
    	else fh=1;
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	x*=fh;
    }
    
    const int maxn=19;
    const int INF=0x3f3f3f3f;
    
    int mx,n;
    int opt[1<<17];
    int t[maxn],w[maxn];
    
    pair<int,int> calc(int x,int y){
    	int res1(0),res2(0);
    	for(int i=1;i<=n;i++){
    		int k=((x>>(i-1))&1),p=((y>>(i-1))&1);
    		if(k==1&&p==0) res1+=w[i],res2=max(res2,t[i]);
    	}
    	return make_pair(res1,res2);
    }
    
    int main(){
    	read(mx);read(n);
    	for(int i=1;i<=n;i++){
    		read(t[i]);read(w[i]);
    	}
    	memset(opt,0x3f,sizeof(opt));
    	opt[0]=0;
    	for(int i=1;i<(1<<n);i++){
    		for(int j=(i-1)&i;1;j=(j-1)&i){
    			int W,T;
    			pair <int,int> pr=calc(i,j);
    			W=pr.first,T=pr.second;
    			if(W<=mx) opt[i]=min(opt[i],opt[j]+T);
    			if(j==0) break;
    		}
    	}
    	printf("%d
    ",opt[(1<<n)-1]);
    	return 0;
    }
    
  • 相关阅读:
    初学JS——利用JS制作的别踩白块儿(街机模式) 小游戏
    对于大数据量的Json解析
    Json数据中的特殊字符处理
    移动端总结和手机兼容问题
    在DW 5.5+PhoneGap+Jquery Mobile下搭建移动开发环境
    HTML5所有标签汇总
    二叉树
    二分查找
    归并排序
    希尔排序
  • 原文地址:https://www.cnblogs.com/liubainian/p/11832889.html
Copyright © 2011-2022 走看看