• 模拟网络流之dp类:1107T3


    http://cplusoj.com/d/senior/p/SS231107C

    可以发现是求第 i i i 层到第 j j j 层的最大流。

    同样先转成最小割,显然割点比个边优。然后我们可以利用状压dp来求。

    f ( i , j , s ) f(i,j,s) f(i,j,s) 表示在第 i i i 层,还可以割 j j j 条边,这层还存活的点集为 s s s,最快在哪里就流不动了。

    我们先假设一条不割从上一层转移。然后我们枚举割哪条从同层转移。

    #include
    using namespace std;
    #ifdef LOCAL
     #define debug(...) fprintf(stdout, ##__VA_ARGS__)
    #else
     #define debug(...) void(0)
    #endif
    #define int long long
    inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
    ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
    x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
    #define Z(x) (x)*(x)
    #define pb push_back
    #define fi first
    #define se second
    //srand(time(0));
    #define N 60010
    #define M 12
    //#define mo
    void Mx(int &a, int b) {
    	a=max(a, b); 
    }
    int n, m, i, j, k, T, t;
    int ans, x, y, s, ns[N][600]; 
    int b[M][M], dp[2][M][600]; 
    char str[M]; 
    
    signed main()
    {
    	freopen("stairs.in", "r", stdin);
    	freopen("stairs.out", "w", stdout);
    	#ifdef LOCAL
    	  freopen("in.txt", "r", stdin);
    	  freopen("out.txt", "w", stdout);
    	#endif
    //	T=read();
    //	while(T--) {
    //
    //	}
    	n=read(); m=read(); 
    	for(i=1; i<n; ++i) {
    		for(x=0; x<m; ++x) {
    			scanf("%s", str); 
    //			debug("%s\n", str); 
    			for(y=0; y<m; ++y) b[x][y]=str[y]-'0'; 
    		}
    		for(s=0; s<(1<<m); ++s) {
    			for(x=0; x<m; ++x) 
    				for(y=0; y<m; ++y)
    					if(((s>>y)&1) && b[x][y]) {
    //						debug("%d %d\n", x, y+m); 
    						ns[i+1][s]|=(1<<x); 
    					}
    //			debug("ns[%d %d]=%d\n", i+1, s, ns[i+1][s]); 
    		}
    		if(i==1) {
    			for(s=0; s<(1<<m); ++s) {
    				for(x=0; x<m; ++x) 
    					for(y=0; y<m; ++y)
    						if(((s>>x)&1) && b[x][y]) {
    							ns[i][s]|=(1<<y); 
    						}
    			}
    		}
    //		debug("\n"); 
    	}
    	for(j=0; j<=m; ++j) {
    		for(s=1; s<(1<<m); ++s) {
    			dp[i&1][j][s]=0; 
    //			if(ns[i][s]==0) dp[i&1][j][s]=2; 
    		}
    		dp[1][j][0]=1; 
    	}
    	for(i=2; i<=n; ++i) {
    		for(j=0; j<=m; ++j) {
    			for(s=0; s<(1<<m); ++s) {
    				dp[i&1][j][s]=0; 
    				if(i==2) {
    					for(k=t=0; k<m; ++k) if((ns[i][s]>>k)&1) ++t; 
    					if(t==j) dp[i&1][j][s]=1; 
    				}
    //				if(ns[i][s]==0) dp[i&1][j][s]=i; 
    			}
    			dp[i&1][j][0]=i; 
    		}
    		for(j=0; j<=m; ++j)
    			for(s=0; s<(1<<m); ++s) 
    				Mx(dp[i&1][j][s], dp[(i&1)^1][j][ns[i][s]]); 
    		for(j=1; j<=m; ++j) 
    			for(s=0; s<(1<<m); ++s) {
    				for(k=0; k<m; ++k) if((s>>k)&1)
    					Mx(dp[i&1][j][s], dp[i&1][j-1][s-(1<<k)]); 
    //				debug("dp[%lld %lld %lld] = %lld\n", i, j, s, dp[i&1][j][s]); 
    			}
    		for(j=m, s=(1<<m)-1; j>=1; --j) {
    			debug("dp[%lld %lld] = %lld \n", i, j, dp[i&1][j][s]) ; 
    			ans+=(dp[i&1][j][s]-dp[i&1][j-1][s])*j; 
    //			if(dp[i&1][j][s]-dp[i&1][j-1][s] && dp[i&1][j][s]==i) ans-=j; 
    		}
    		ans-=m; 
    		debug("%lld\n", ans); 
    	}
    		
    	printf("%lld", ans); 
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
  • 相关阅读:
    vue-router 路由
    uniapp微信小程序地图实现周边
    数组c++介绍
    贪心算法-构造哈夫曼数及生成哈夫曼编码,编程实现
    Mysql002:(库和表)操作SQL语句
    热用图片怎么表示简笔画,网络简笔画图片大全
    nodejs安装及环境配置详细教程
    什么是DES算法,详解DES算法的基本原理
    docker 数据 迁移
    安科瑞智能母线监控在数据中心的应用
  • 原文地址:https://blog.csdn.net/zhangtingxiqwq/article/details/134275008