P2045 方格取数加强版
P2045 方格取数加强版
题目描述
给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大
输入输出格式
输入格式:
第一行两个数n,k(1<=n<=50, 0<=k<=10)
接下来n行,每行n个数,分别表示矩阵的每个格子的数
输出格式:
一个数,为最大和
输入输出样例
说明
每个格子中的数不超过1000
相信一定有一些人一看到N<=50就想搜索(233……),但是显然TLE。
那么对于K<=10,我记得当k<=2时,貌似用DP也能做。
这题的坑就在于“加强版”,其实这题是个图论。
再看看,不难想到这是网络流“最大流最大消费”,再看到aij<=1000,便可以将每个数取负数,就最小消费流即可。
怎么建图,是网络流中的难点。
因为每个点只能去一次,所以拆成两点,这两点之间有两条路,一条只能走一次(流量为1),但可以取到数(费用为-aij)
另一点最多能走k次,取不到数。
有人喜欢建超级源点和汇点(因为只取k次),其实不用如此。
我们从1,1点出发SPFAk次即可,注意如果有一次到不了终点直接结束!
OK,就这样AC了。注意点的位置,我用的是pos(i,j)=(i-1)*n+j,比较方便。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define pos(i,j) (i-1)*n+j
using namespace std;
+;
*;
struct p
{
int to,w,cost,nxt;
}e[M];
],dis[N<<],pre[N<<];
];
int x,num,n,k,cnt;
void add(int u,int v,int ds,int cst)
{
e[cnt].nxt=h[u];
e[cnt].to=v;
e[cnt].w=ds;
e[cnt].cost=cst;
h[u]=cnt;
cnt++;
e[cnt].nxt=h[v];
e[cnt].to=u;
e[cnt].w=;
e[cnt].cost=-cst;
h[v]=cnt;
cnt++;
}
int solve()
{
;
while(k--)
{
memset(dis,0x3f,sizeof(dis));
memset(pre,-,sizeof(pre));
queue<int>q;
q.push();
dis[]=;
while(!q.empty())
{
int now=q.front();
q.pop();inq[now]=;
;i=e[i].nxt)
if(e[i].w&&dis[e[i].to]>dis[now]+e[i].cost)
{
dis[e[i].to]=dis[now]+e[i].cost;
pre[e[i].to]=i;
;
}
}
) return -ans;
,j=n*n+N;
)
{
mx=min(mx,e[pre[j]].w);
j=e[pre[j]^].to;
}
j=n*n+N;
)
{
ans+=e[pre[j]].cost*mx;
e[pre[j]].w-=mx;
e[pre[j]^].w+=mx;
j=e[pre[j]^].to;
}
}
return -ans;
}
int main()
{
memset(h,-,sizeof(h));
scanf("%d%d",&n,&k);
;i<=n;i++)
;j<=n;j++)
{
scanf("%d",&x);
num=pos(i,j);
add(num,num+N,,-x);add(num,num+N,k,);
,j),k,);
),k,);
}
printf("%d",solve());
;
}
P2045 方格取数加强版的更多相关文章
- 洛谷 P2045 方格取数加强版【费用流】
题目链接:https://www.luogu.org/problemnew/show/P2045 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现 ...
- P2045 方格取数加强版 最大费用最大流
$ \color{#0066ff}{ 题目描述 }$ 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每 ...
- [洛谷P2045]方格取数加强版
题目大意:有一个n*n的矩阵,每个格子有一个非负整数,规定一个人从(1,1)开始,只能往右或下走,走到(n,n)为止,并把沿途的数取走,取走后数变为0.这个人共取n次,求取得的数的最大总和. 解题思路 ...
- 洛谷 - P2045 - 方格取数加强版 - 费用流
原来这种题的解法是费用流. 从一个方格的左上走到右下,最多走k次,每个数最多拿走一次. 每次走动的流量设为1,起始点拆点成限制流量k. 每个点拆成两条路,一条路限制流量1,费用为价值相反数.另一条路无 ...
- bzoj P2045 方格取数加强版【最大费用最大流】
今天脑子不太清醒,把数据范围看小了一直TTTTLE-- 最大费用最大流,每个格子拆成两个(x,y),(x,y)',(x,y)向(x,y)'连一条费用a[x][y]流量1的边表示选的一次,再连一条费用0 ...
- 洛谷P2045 方格取数加强版(费用流)
题意 题目链接 Sol 这题能想到费用流就不难做了 从S向(1, 1)连费用为0,流量为K的边 从(n, n)向T连费用为0,流量为K的边 对于每个点我们可以拆点限流,同时为了保证每个点只被经过一次, ...
- 【Luogu】P2045方格取数加强版(最小费用最大流)
题目链接 通过这题我学会了引诱算法的行为,就是你通过适当的状态设计,引诱算法按照你想要它做的去行动,进而达到解题的目的. 最小费用最大流,首先将点拆点,入点和出点连一条费用=-权值,容量=1的边,再连 ...
- 洛谷P2045 方格取数加强版 最小费用流
Code: #include<cstdio> #include<cstring> #include<algorithm> #include<queue> ...
- [luogu_P2045]方格取数加强版
[luogu_P2045]方格取数加强版 试题描述 给出一个 \(n \times n\) 的矩阵,每一格有一个非负整数 \(A_{i,j},(A_{i,j} \le 1000)\) 现在从 \((1 ...
随机推荐
- 浅谈JavaScript的面向对象程序设计(二)
前面介绍通过Object构造函数或者字面量创建单个对象,但是通过这个的方法创建对象有明显的缺点:调用同一个接口创建多个实例,会产生大量的重复代码.怎么样解决? 工厂模式 工厂模式是软件工程领域经常使用 ...
- Wechat 微信端调用“微信支付接口”的正确方式
微信端的项目中,比如微信商城之类的,肯定会涉及到微信支付这一块: 下面直接上详细的代码: var data = {--}; // 调用微信支付需要的数据 function onBridgeReady( ...
- python基础(四)字符串处理
字符串处理 msg = 'my name is sylar' capitalize方法,将字符串的首字母大写 print 'capitalize方法:', msg.capitalize() swapc ...
- C语言中不同变量的访问方式
C语言中的变量大致可以分为全局变量,局部变量,堆变量和静态局部变量,这些不同的变量存储在不同的位置,有不同的生命周期.一般程序将内存分为数据段.代码段.栈段.堆段,这几类变量存储在不同的段中,造成了它 ...
- String常用的方法
l String: 字符串类,字符串是常量:它们的值在创建之后不能更改 l 方法 boolean equals(Object obj) 判断两个字符串中的内容是否相同 boolean equalsIg ...
- chromedriver对应的支持的Chrome版本(更新至Chrome63)
很多网友在配置chromedriver的时候会遇到很多麻烦,在网上找了很多资料觉得这个表格不错,就给大家分享出来,希望对大家配置chrome的时候有帮助: chromedriver版本 支持的Chro ...
- 浅谈我的MongoDB学习(一)
这是第一次写博客,不当之处敬请见谅,最近由于项目需要,对mongodb略有研究,网上也有一些相关资料,下面是我自己摸索的一些东西,希望能跟大家分享一下当然,这也是我自己第一次在项目中使用,若理解有误, ...
- DAY5-小别-2018-1-15
有两天没有写了,前天考完试出去浪了,惭愧自己没有学习:昨天,启程回家看完了循环内容的视频,晚上十点半火车到站,没抽出时间写了,还看了<黑客帝国>,有点小感触,人工智能的时代即将到来,我们该 ...
- python 错误:"'NoneType' object has no attribute 'execute'"
这种原因常常是数据库链接产生的错误,检查连接参数时候齐全,cursor是否获取到了.
- Go并发模式:管道与取消
关键字:Go语言,管道,取消机制,并发,sync.WaitGroup,包引用,通道,defer,select GO并发模式:管道与取消 简介 Go的并发能力可以使构建一个流数据管道变得非常容易,并且可 ...