poj 3422 洛谷P2045 K取方格数(方格取数加强版)

Description:

给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大

Input:

第一行两个数n,k(1<=n<=50, 0<=k<=10)

接下来n行,每行n个数,分别表示矩阵的每个格子的数

Output:

一个数,为最大和

思路:仍旧是拆点 因为每个点都有一个限制K和一个价值V 所以将一个点拆成两个点,对相邻的点连两条边,一条费用为V,限制为1, 一条费用为0,限制为K - 1。然后跑个最大费用最大流即可

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 50100, M = 2000100;
int d[N], incf[N], pre[N], n, k, s, t, maxflow, ans;
bool vis[N];

int head[N],now;
struct edges{
    int to,next,lim,w;
}edge[N<<1];
void add(int x,int y,int z,int c){
    edge[++now] = {y,head[x],z,c};
    head[x] = now;
    edge[++now] = {x,head[y],0,-c};
    head[y] = now;
}

int id(int i,int j,int k){    return (i - 1)*n + j + k * n * n;}

bool spfa(){
    queue<int> q;
    memset(d,0xcf,sizeof(d));
    memset(vis,0,sizeof(vis));
    q.push(s); d[s] = 0; vis[s] = 1;
    incf[s] = 1e9;
    while(!q.empty()){
        int x = q.front(); vis[x] = 0; q.pop();
        for(int i = head[x]; i; i = edge[i].next){
            int v = edge[i].to;
            if(!edge[i].lim) continue;
            if(d[v] < d[x] + edge[i].w){
                d[v] = d[x] + edge[i].w;
                incf[v] = min(incf[x], edge[i].lim);
                pre[v] = i;
                if(!vis[v]) vis[v] = 1, q.push(v);
            }
        }
    }
    if(d[t] == 0xcfcfcfcf) return 0;
    return 1;
}
void update(){
    int x = t;
    while(x != s){
        int i = pre[x];
        edge[i].lim -= incf[t];
        edge[i ^ 1].lim += incf[t];
        x = edge[i ^ 1].to;
    }
    maxflow += incf[t];
    ans += d[t] * incf[t];
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>k;
    s = 1, t = 2*n*n;
    now = 1;
    int x;
    for(int i = 1; i <= n; i++)
      for(int j = 1; j <= n; j++){
        cin>>x;
        add(id(i,j,0),id(i,j,1),1,x);
        add(id(i,j,0),id(i,j,1),k - 1,0);
        if(j < n) add(id(i,j,1),id(i,j+1,0),k,0);
        if(i < n) add(id(i,j,1),id(i+1,j,0),k,0);
      }
    while(spfa())
     update();
    cout<<ans<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/Rorshach/p/8684541.html

时间: 2024-11-08 13:33:31

poj 3422 洛谷P2045 K取方格数(方格取数加强版)的相关文章

[洛谷P2045]方格取数加强版

题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0.这个人共取n次,求取得的数的最大总和. 解题思路:由于取多少次不确定,所以不能用dp. 我们发现,一个格子只能从左边或上面走来,且数只能取到一次,那么我们可以把此题转化为最大费用最大流问题.首先拆点,将一个点拆成x和y,然后从x到y连一条容量为1,流量为x(x为这格的数)的边,然后再连一条容量为inf,费用为0的边,这样即可保证一个点可以走多次,

洛谷2105 k皇后

P2105 K皇后 题目描述 小Z最近捡到了一个棋盘,他想在棋盘上摆放K个皇后.他想知道在他摆完这K个皇后之后,棋盘上还有多少了格子是不会被攻击到的. (Ps:一个皇后会攻击到这个皇后所在的那一行,那一列,以及两条对角线) 输入输出格式 输入格式: 第一行三个正整数 n,m,K,表示棋盘的行列,以及小Z摆放了K个皇后. 接下来K行,每行两个正整数x,y,表示这个皇后被摆在了第x行,第y列,数据保证没有任何两个皇后会被摆在同一个格子里. 输出格式: 一行一个整数,表示棋盘上还有多少了格子是不会被攻

洛谷 P2105 K皇后

P2105 K皇后 题目描述 小Z最近捡到了一个棋盘,他想在棋盘上摆放K个皇后.他想知道在他摆完这K个皇后之后,棋盘上还有多少了格子是不会被攻击到的. (Ps:一个皇后会攻击到这个皇后所在的那一行,那一列,以及两条对角线) 输入输出格式 输入格式: 第一行三个正整数 n,m,K,表示棋盘的行列,以及小Z摆放了K个皇后. 接下来K行,每行两个正整数x,y,表示这个皇后被摆在了第x行,第y列,数据保证没有任何两个皇后会被摆在同一个格子里. 输出格式: 一行一个整数,表示棋盘上还有多少了格子是不会被攻

poj 1717==洛谷P1282 多米诺骨牌

Dominoes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6571   Accepted: 2178 Description A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank or bearing from one to six dots. There is a ro

洛谷P3200 [HNOI2009]有趣的数列(Catalan数)

P3200 [HNOI2009]有趣的数列 题目描述 我们称一个长度为2n的数列是有趣的,当且仅当该数列满足以下三个条件: (1)它是从1到2n共2n个整数的一个排列{ai}: (2)所有的奇数项满足a1<a3<...<a2n-1,所有的偶数项满足a2<a4<...<a2n: (3)任意相邻的两项a2i-1与a2i(1<=i<=n)满足奇数项小于偶数项,即:a2i-1<a2i. 现在的任务是:对于给定的n,请求出有多少个不同的长度为2n的有趣的数列.因

洛谷 P2774 方格取数问题

题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法.对于给定的方格棋盘,按照取数要求编程找出总和最大的数. 输入输出格式 输入格式: 第 1 行有 2 个正整数 m 和 n,分别表示棋盘的行数和列数.接下来的 m 行,每行有 n 个正整数,表示棋盘方格中的数. 输出格式: 程序运行结束时,将取数的最大总和输出 输入输出样例 输入样例#1: 3 3 1 2

【动态规划】洛谷P1004方格取数

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上

方格取数洛谷p1004

题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B 点.在走过的路上

洛谷1004方格取数

P1004 方格取数 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 14 0 0 0 0 0 21 0 0 0 4 0 0 0 0 15 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . B 某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角