[Vijos 1143]三取方格数
Description
设有N*N的方格图,我们将其中的某些方格填入正整数,
而其他的方格中放入0。
某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。
在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)
此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。
Input
第一行:N (4<=N<=20)
接下来一个N*N的矩阵,矩阵中每个元素不超过80,不小于0
Output
Sample Input
4
1 2 3 4
2 1 3 4
1 2 3 4
1 3 2 4
Sample Output
39
题解(转载)
$DP$好题。
这里给出费用流的做法:
拆点建图,每一个点都拆成两个点,在这里就称为出点和入点。
出点和入点建两条边,一条费用为$s[i][j]$,流量为$1$;一条费用为$0$,流量为$inf$。(分别表示选择这个点和从这个点上经过)
将$(i,j)$的出点分别和$(i+1,j)$$(i,j+1)$的入点建边,流量为$inf$,费用为$0$。(表示行进)
跑一边最大费用最大流就可以了。
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
const int INF = ~0u>>; int n;
int a[][];
struct tt{
int to, cost, next, cap;
}edge[];
int path[], top = -;
void Add(int u, int v, int cost, int cap);
int sta = , fin = ;
int min_cost_flow();
int SPFA(); int main(){
memset(path, -, sizeof(path));
scanf("%d", &n);
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
scanf("%d", &a[i][j]);
for (int i = ; i < n; i++)
for (int j = ; j < n; j++){
Add(i*n+j, (i+n)*n+j, a[i][j], );
Add(i*n+j, (i+n)*n+j, , INF);
if (i != n-) Add((i+n)*n+j, (i+)*n+j, , INF);
if (j != n-) Add((i+n)*n+j, i*n+j+, , INF);
}
Add(sta, , , );
Add((*n-)*n+n-, fin, ,);
printf("%d\n", min_cost_flow());
return ;
} void Add(int u, int v, int cost, int cap){
edge[++top].to = v;
edge[top].cost = cost;
edge[top].cap = cap;
edge[top].next = path[u];
path[u] = top;
edge[++top].to = u;
edge[top].cost = -cost;
edge[top].cap = ;
edge[top].next = path[v];
path[v] = top;
}
int min_cost_flow(){
int tolcost = ;
int tmp;
while (tmp = SPFA()) tolcost += tmp;
return tolcost;
}
int SPFA(){
int dist[];
memset(dist, , sizeof(dist)); dist[sta] = ; dist[fin] = -INF;
bool vis[] = {}; vis[sta] = ;
queue<int>Q;
while (!Q.empty()) Q.pop();
Q.push(sta);
int pre[] = {};
while (!Q.empty()){
int u = Q.front(); Q.pop(); vis[u]=;
for (int i = path[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if (dist[v] < dist[u]+edge[i].cost && edge[i].cap > ){
dist[v] = dist[u]+edge[i].cost;
pre[v] = i;
if (!vis[v]){
vis[v] = ;
Q.push(v);
}
}
}
}
if (dist[fin] == -INF) return ;
int minflow = INF;
for (int i = fin; i != sta; i = edge[pre[i]^].to)
minflow = Min(minflow, edge[pre[i]].cap);
for (int i = fin; i != sta; i = edge[pre[i]^].to)
edge[pre[i]].cap -= minflow,
edge[pre[i]^].cap += minflow;
return dist[fin];
}
[Vijos 1143]三取方格数的更多相关文章
- 【动态规划】Vijos P1143 三取方格数(NOIP2000提高组)
题目链接: https://vijos.org/p/1143 题目大意: NxN的矩阵,每个值只能取一次,从(1,1)走到(n,n)走三次能取得的最大值. 题目思路: [动态规划] f[x1][y1] ...
- begin.BZOJ 1383: 三取方格数
题目链接:传送门 题目大意:给你一个矩阵,每个格子有一个值,现在你要从左上角走到右下角(走3次),使得经过路径的权值和最大. 每个格子的值只能取一次,取完后变为0,输出走完三次后最大的权值和. 题目思 ...
- POJ 3422 Kaka's Matrix Travels (K取方格数:最大费用流)
题意 给出一个n*n大小的矩阵,要求从左上角走到右下角,每次只能向下走或者向右走并取数,某位置取过数之后就只为数值0,现在求解从左上角到右下角走K次的最大值. 思路 经典的费用流模型:K取方格数. 构 ...
- Luogu2045 方格取数加强版(K取方格数) 费用流
题目传送门 题意:给出一个$N \times N$的方格,每个格子中有一个数字.你可以取$K$次数,每次取数从左上角的方格开始,每一次只能向右或向下走一格,走到右下角结束,沿路的方格中的数字将会被取出 ...
- poj 3422 洛谷P2045 K取方格数(方格取数加强版)
Description: 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来 ...
- POJ 3422 Kaka's Matrix Travels K取方格数
题目:给出n*n的方格矩阵,现在从左上方走m次到右下方,问m次能够获得的最大价值和. 分析:最大费用流.拆点进行限制每个格子只取一次,假设点x拆成 x,xx,右边(假设有)y,yy,下方(假设有)z, ...
- vijos 1563 疯狂的方格取数
P1653疯狂的方格取数 Accepted 标签:天才的talent[显示标签] 背景 Due to the talent of talent123,当talent123做完NOIP考了两次的二取 ...
- php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中)
php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中) 一.总结 1.if(isset($arr[$val])) $arr[$val]++; //1 ...
- 一个hin秀的小学三年级奥数题 [hin秀]
~~~~~~不知为何总会被小学的题虐哭QAQ,真的秀啊,毒害广大小朋友~~~~~~ 一个hin秀的小学三年级奥数题 [hin秀] 题目: 给出一个无限大的棋盘 n×n (n>0 , 是 ...
随机推荐
- QT5.8 for embedded
http://doc.qt.io/qt-5/embedded-linux.html 先占座~
- c语言的第三次---单程循环结构
一.PTA实验作业 题目1 1.代码 int N,i; double height; //height代表身高 char sex; //代表男女性别 scanf("%d",& ...
- 【Alpha版本】冲刺阶段 - Day2 - 漂流
今日进展 袁逸灏:实现车辆的子弹发射(3.5h) 启动类,子弹类(修改类),游戏画面类(修改类) 刘伟康:继续借鉴其他 alpha 冲刺博客,初步了解墨刀.leangoo等工具(2h) 刘先润:解决了 ...
- 201621123062《Java程序设计》第一周学习总结
1.本周学习总结 关键词: 初步熟悉Java的基本组成.语言特点(简单性.结构中立性).运行环境.简单语法等. 关键概念之间的联系: 1.JVM是Java程序唯一认识的操作系统,其可执行文件为.cla ...
- Git学习使用
1.注册码云并建立远程仓库 2.安装git 3.使用eclipse egit 推送以及克隆 建立本地仓库,成功后如图 推送项目至本地仓库与远程仓库 使用右键菜单team-share 选项,与仓库关联后 ...
- dede使用心得
Question one: 最近做了一些视频教程传到优酷网站上,但我想引入这些视频教程到我的网站,在发表时我发现织梦CMS自带的编辑器又不直接支持优酷等视频网站的引用.所以为了方便教程的发布,特意在网 ...
- rsync 自动创建目录的坑点
rsync同步文件有三种模式: 1.把源站路径下某个文件,同步到目标路径.例如rsync -aR /data/1/2/3/a.txt 1.1.1.1:/data/ ,目标机器将自动创建多层目录存放a. ...
- SiteMesh在项目中的配置
SiteMesh在项目中的配置 首先在web.xml里面增加siteMesh的配置: <filter> <filter-name>sitemesh</filter-nam ...
- SpringBoot入门:新一代Java模板引擎Thymeleaf(实践)
菜鸟教程:http://www.runoob.com/ http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js http://apps.b ...
- word2vec初探(用python简单实现)
为什么要用这个? 因为看论文和博客的时候很常见,不论是干嘛的,既然这么火,不妨试试. 如何安装 从网上爬数据下来 对数据进行过滤.分词 用word2vec进行近义词查找等操作 完整的工程传到了我的gi ...