思路:

dp方法:

    设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值。

    则转移方程为

    dp[i][j][k][l]=max(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k][l-1])+map[i][j]+map[k][l];

    若两点相同减去一个map[i][j]即可

 

费用流方法(可以扩展为k条路径,但时间复杂度较高):

    源点连接左上角点流量为k、费用为0,右下角点连接汇点流量为k、费用为0,所有点连接右边相邻和下边相邻点流量为k、费用为0,所有点拆点一条流量为1、费用为该

    点价值,一条流量为k-1、费用为0。跑最大费用流即可

 

 

代码:

dp:

 1 #include <cstdio>  
 2 #include <cstring>  
 3 #include <algorithm>  
 4 #include <iostream>  
 5 #include <vector>  
 6 #include <queue>  
 7 #include <cmath>  
 8 #include <set>  
 9 using namespace std;  
10   
11 #define N 55
12 
13 __int64 map[N][N];
14 __int64 dp[N][N][N][N];
15 int n, m;
16 
17 main()
18 {
19     int i, j, k, l;
20     int x, y, w;
21     while(scanf("%d %d",&n,&m)==2){
22         memset(map,0,sizeof(map));
23         memset(dp,0,sizeof(dp));
24         for(i=1;i<=n;i++){
25             for(j=1;j<=m;j++){
26                 scanf("%I64d",&map[i][j]);
27             }
28         }
29         for(i=1;i<=n;i++){
30             for(j=1;j<=m;j++){
31                 for(k=1;k<=n;k++){
32                     for(l=1;l<=m;l++){
33                         dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k-1][l]);
34                         dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k-1][l]);
35                         dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l-1]);
36                         dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l-1]);
37                         dp[i][j][k][l]+=map[i][j]+map[k][l];
38                         if(i==k&&j==l) dp[i][j][k][l]-=map[i][j];
39                     }
40                 }
41             }
42         }
43         printf("%I64d\n",dp[n][m][n][m]);
44     }
45 }
View Code

费用流:

  1 #include <cstdio>  
  2 #include <cstring>  
  3 #include <algorithm>  
  4 #include <iostream>  
  5 #include <vector>  
  6 #include <queue>  
  7 #include <cmath>  
  8 #include <set>  
  9 using namespace std;  
 10   
 11 #define N 205  
 12 #define M 1005  
 13 #define inf 999999999  
 14   
 15 struct MCF{//min_cost_flow  
 16     struct Edge{  
 17         int v, f, w, next;  
 18         Edge(){};  
 19         Edge(int a,int b,int c,int d){  
 20             v=a;f=b;w=c;next=d;  
 21         }  
 22     };  
 23     int n;  
 24     int head[N+10];  
 25     Edge e[M*2];  
 26     int nume;  
 27     int src, sink;  
 28        
 29     void init(int st, int end,int nn){//初始化   
 30         src=st;sink=end;n=nn;  
 31         memset(head,0,sizeof(head));  
 32         nume=1;  
 33     }     
 34        
 35     void addedge(int u,int v,int c,int w){  
 36         e[++nume]=Edge(v,c,w,head[u]);  
 37         head[u]=nume;  
 38         e[++nume]=Edge(u,0,-w,head[v]);  
 39         head[v]=nume;  
 40     }  
 41        
 42        
 43     queue<int>Q;  
 44     bool visited[N];  
 45     int dis[N];  
 46     int prev[N], pree[N];  
 47        
 48     bool findpath(){  
 49            
 50         while(!Q.empty()) Q.pop();  
 51         Q.push(src);  
 52         for(int i=0;i<=n;i++) dis[i]=-1;  
 53         dis[src]=0;  
 54         visited[src]=true;  
 55         while(!Q.empty()){  
 56             int u=Q.front();Q.pop();visited[u]=false;  
 57             for(int i=head[u];i;i=e[i].next){  
 58                 if(e[i].f>0&&dis[u]+e[i].w>dis[e[i].v]){  
 59                     dis[e[i].v]=dis[u]+e[i].w;  
 60                     prev[e[i].v]=u;  
 61                     pree[e[i].v]=i;  
 62                     if(!visited[e[i].v]){  
 63                         Q.push(e[i].v);  
 64                         visited[e[i].v]=true;  
 65                     }  
 66                 }  
 67             }  
 68         }//printf("111111\n");  
 69         if(dis[sink]>0) return true;  
 70         else return false;  
 71     }  
 72        
 73     int solve(){  
 74            
 75         int u=sink;  
 76         int flow=inf;  
 77         while(u!=src){  
 78             if(e[pree[u]].f<flow) flow=e[pree[u]].f;  
 79             u=prev[u];  
 80         }  
 81         u=sink;  
 82         while(u!=src){  
 83             e[pree[u]].f-=flow;  
 84             e[pree[u]^1].f+=flow;  
 85             u=prev[u];  
 86         }  
 87            
 88         return dis[sink]*flow;  
 89     }  
 90        
 91     int mincostflow(){  
 92         int ans=0;  
 93         while(findpath()){  
 94             ans+=solve();  
 95         }  
 96         return ans;  
 97     }  
 98 }mcf;  
 99   
100 int n;  
101 int map[10][10];  
102   
103 int x, y, w;  
104   
105 main()  
106 {  
107     int i, j, k;  
108     while(scanf("%d",&n)==1){  
109         memset(map,0,sizeof(map));  
110         while(1){  
111           
112             scanf("%d %d %d",&x,&y,&w);  
113             if(x==0&&y==0&&w==0) break;  
114             map[x][y]=w;  
115         }  
116         mcf.init(0,n*n*2+1,n*n*2+2);  
117         mcf.addedge(0,1,2,0);  
118         mcf.addedge(n*n*2,n*n*2+1,2,0);  
119         int temp=1;  
120         for(i=1;i<=n;i++){  
121             for(j=1;j<=n;j++){  
122                 mcf.addedge(temp,temp+n*n,1,map[i][j]);  
123                 mcf.addedge(temp,temp+n*n,1,0);  
124                 if(i<n) mcf.addedge(temp+n*n,temp+n,2,0);  
125                 if(j<n) mcf.addedge(temp+n*n,temp+1,2,0);  
126                 temp++;  
127             }  
128         }  
129         printf("%d\n",mcf.mincostflow());  
130     }  
131 }  
View Code

 

posted on 2015-09-01 12:34  MC幽夜  阅读(202)  评论(0编辑  收藏  举报