zoukankan      html  css  js  c++  java
  • 洛谷 1004 dp或最大费用流

    思路:

    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
    ",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
    ");  
     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
    ",mcf.mincostflow());  
    130     }  
    131 }  
    View Code
  • 相关阅读:
    新博客第一篇,字符串 Unicode 转义
    C# 泛型方法的类型推断
    一个改进 LRU 算法的缓冲池 update 2013.7.15
    C# 判断类型间能否隐式或强制类型转换,以及开放泛型类型转换 update 2015.02.03
    C# 词法分析器(三)正则表达式
    java面试题(二)
    Map的迭代
    Spring aop切面插入事物回滚
    Log4J的配置
    js中将yyyyMMdd格式的日期转换
  • 原文地址:https://www.cnblogs.com/qq1012662902/p/4775385.html
Copyright © 2011-2022 走看看