zoukankan      html  css  js  c++  java
  • POJ3422 Kaka's Matrix Travels

    Kaka's Matrix Travels

    Language:
    Kaka's Matrix Travels
    Time Limit: 1000MSMemory Limit: 65536K
    Total Submissions: 10892Accepted: 4444

    Description

    On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during the K travels.

    Input

    The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are no more than 1000.

    Output

    The maximum SUM Kaka can obtain after his Kth travel.

    Sample Input

    3 2
    1 2 3
    0 2 1
    1 4 2
    

    Sample Output

    15

    Source

    POJ Monthly--2007.10.06, Huang, Jinsong

    有一个人要在从矩阵的左上角走到右下角K次,他只能向下或者向右走,且矩阵中的每个格子有着自己的分数,第一次到达后可以拾取这个分数,随后到达的时候就没有分数了,问这个人K次之后能拾取的最大分数是多少。

    题解

    一个点可以走多次,而且第二次走没有分数。解决方法是,拆点。每个点到它拆出来的点连两条边,一条的容量设成1,费用设为该格子分数的相反数。表示,这条边只能走一次,且走这条边能拿到分数;第二条的容量设成k-1,费用设成0,表示,这个格子可以重复走,但是没有分数。然后在拆出来的点和它能到的点连边,容量k-1,费用为0就可以了。 然后跑最大费用最大流。

    #include<iostream>
    #include<cstring>
    #include<queue>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
        for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    using namespace std;
    
    co int N=5e3+1,M=2e5+1;
    int ver[M],edge[M],cost[M],next[M],head[N];
    int d[N],incf[N],pre[N],v[N];
    int n,k,tot,s,t,maxflow,ans;
    
    il void add(int x,int y,int z,int c){
    	ver[++tot]=y,edge[tot]=z,cost[tot]=c,next[tot]=head[x],head[x]=tot;
    	ver[++tot]=x,edge[tot]=0,cost[tot]=-c,next[tot]=head[y],head[y]=tot;
    }
    il int num(int i,int j,int k){
    	return (i-1)*n+j+k*n*n;
    }
    bool spfa(){
    	memset(d,0xcf,sizeof d),d[s]=0;
    	queue<int> q;q.push(s);
    	memset(v,0,sizeof v),v[s]=1;
    	incf[s]=1e9;
    	while(q.size()){
    		int x=q.front();q.pop(),v[x]=0;
    		for(int i=head[x];i;i=next[i]){
    			if(!edge[i]) continue;
    			int y=ver[i];
    			if(d[y]<d[x]+cost[i]){
    				d[y]=d[x]+cost[i];
    				incf[y]=min(incf[x],edge[i]);
    				pre[y]=i;
    				if(!v[y]) q.push(y),v[y]=1;
    			}
    		}
    	}
    	return d[t]!=0xcfcfcfcf;
    }
    void update(){
    	int x=t;
    	while(x!=s){
    		int i=pre[x];
    		edge[i]-=incf[t],edge[i^1]+=incf[t];
    		x=ver[i^1];
    	}
    	maxflow+=incf[t],ans+=d[t]*incf[t];
    }
    int main(){
    	read(n),read(k),s=1,t=2*n*n;
    	tot=1;
    	for(int i=1;i<=n;++i)for(int j=1;j<=n;++j){
    		int c=read<int>();
    		add(num(i,j,0),num(i,j,1),1,c);
    		add(num(i,j,0),num(i,j,1),k-1,0);
    		if(j<n) add(num(i,j,1),num(i,j+1,0),k,0);
    		if(i<n) add(num(i,j,1),num(i+1,j,0),k,0);
    	}
    	while(spfa()) update();
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Vue学习笔记【28】——Vue路由(使用 children 属性实现路由嵌套)
    Vue学习笔记【27】——Vue路由(设置路由)
    Vue学习笔记【26】——Vue路由(什么是路由)
    Vue学习笔记【25】——Vue组件(组件间传值)
    Vue学习笔记【24】——Vue组件(组件切换)
    Vue学习笔记【23】——Vue组件(组件的定义)
    ga统计
    token验证机制
    网站发布(项目上线流程)
    使用CSS将图片转换成黑白(灰色、置灰) & 毛玻璃效果
  • 原文地址:https://www.cnblogs.com/autoint/p/11002677.html
Copyright © 2011-2022 走看看