zoukankan      html  css  js  c++  java
  • NOI题库 / 2.6基本算法之动态规划

    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    一个商人穿过一个 N*N 的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。

    这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?

    注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。

    输入
    第一行是一个整数,表示正方形的宽度N (1 <= N < 100);
    后面 N 行,每行 N 个不大于 100 的整数,为网格上每个小方格的费用。
    输出
    至少需要的费用。
    样例输入
    5
    1 4 6 8 10 
    2 5 7 15 17 
    6 8 9 18 20 
    10 11 12 19 21 
    20 23 25 29 33 
    样例输出
    109
    提示
    样例中,最小值为109=1+2+5+7+9+12+19+21+33。
    来源
    元培-From Whf
    题目链接
    费用流 
    #include <cstdio>
    #include <queue>
    #define M 100000
    #define N 105
    #define inf 0x3f3f3f3f
    
    using namespace std;
    bool inq[N];
    int n,S,T,cnt=1,fx[5]= {1,-1,0,0},fy[5]= {0,0,-1,1},a[N][N],to[M<<1],dis[M],fa[M],head[M],came[M<<1],nxt[M<<1],flow[M<<1],cost[M<<1];
    void ins(int u,int v,int w,int f)
    {
        nxt[++cnt]=head[u];to[cnt]=v;flow[cnt]=w;cost[cnt]=f;head[u]=cnt;
        nxt[++cnt]=head[v];to[cnt]=u;flow[cnt]=0;cost[cnt]=-f;head[v]=cnt;
    }
    bool spfa()
    {
        for(int i=S; i<=T; ++i) dis[i]=inf,inq[i]=false,came[i]=inf;
        queue<int>q;
        dis[S]=0;
        q.push(S);
        for(int u; !q.empty();)
        {
            u=q.front();
            q.pop();
            inq[u]=false;
            for(int i=head[u]; i; i=nxt[i])
            {
                int v=to[i];
                if(dis[v]>dis[u]+cost[i]&&flow[i])
                {
                    dis[v]=dis[u]+cost[i];
                    fa[v]=i;
                    came[v]=min(came[u],flow[i]);
                    if(!inq[v])
                    {
                        inq[v]=true;
                        q.push(v);
                    }
                }
            }
        }
        return dis[T]<inf;
    }
    int main(int argc,char *argv[])
    {
        scanf("%d",&n);
        S=0;
        T=n*n*2+1;
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
                scanf("%d",&a[i][j]);
        ins(S,1,inf,a[1][1]);
        ins(n*n,T,inf,0);
        for(int i=1; i<=n; ++i)
        {
            for(int j=1; j<=n; ++j)
            {
                ins((i-1)*n+j,(i-1)*n+j+n*n,1,0);
                for(int k=0; k<4; ++k)
                {
                    int ti=i+fx[k],tj=j+fy[k];
                    if(ti<1||ti>n||tj<1||tj>n) continue;
                    ins((i-1)*n+j+n*n,(ti-1)*n+tj,1,a[ti][tj]);
                }
            }
        }
        int ans=0;
        while(spfa())
        {
            int t=came[T];
            for(int i=T; i!=S; i=to[fa[i]^1])
            {
                flow[fa[i]]-=t;
                flow[fa[i]^1]+=t;
            }
            ans+=t*dis[T];
        }
        printf("%d
    ",ans);
        return 0;
    }

    dp

    #include<iostream>
    using namespace std;
    int n,a[118][118],f[118][118];
    int main()
    {
        cin>>n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                cin>>a[i][j];
                if(j==1)
                    f[i][j]=f[i-1][j]+a[i][j];
                else if(i==1)
                    f[i][j]=f[i][j-1]+a[i][j];
                else
                    f[i][j]=min(f[i-1][j]+a[i][j],f[i][j-1]+a[i][j]);
            }
        cout<<f[n][n];
        return 0;
    }
  • 相关阅读:
    SSH应用
    [数字信号处理]IIR滤波器的间接设计(C代码)
    C#调用ATL COM
    【deep learning学习笔记】最近读的几个ppt(未完...)
    程序中输出两位小数
    Exchange Server 2007 部署:安装时的 10 条提示
    中兴通讯变卖资产首季实现扭亏
    iPhone市场份额急跌 苹果亟需新产品确保市场地位
    如何做一个真正牛X 的开源项目
    提高PHP编程效率的53种方法
  • 原文地址:https://www.cnblogs.com/sy1in/p/7853675.html
Copyright © 2011-2022 走看看