GESP编程共123题,本题是整站第1439题,已经有人完成了本题,加油!
小杨有一个有一个 n×m 的矩阵,仅包含 01?
三种字符。矩阵的行从上到下编号依次为 1,2,…,n,列从左到右编号依次为 1,2,…,m。小杨开始在矩阵的左上角 (1,1),小杨只能向下或者向右移动,最终到达右下角 (n,m) 时停止,在移动的过程中每经过一个字符 1
得分会增加一分(包括起点和终点),经过其它字符则分数不变。小杨的初始分数为 0 分。
小杨可以将矩阵中不超过 x 个字符 ?
变为字符 1
。小杨在修改矩阵后,会以最优的策略从左上角移动到右下角。他想知道自己最多能获得多少分。
第一行包含一个正整数 t,代表测试用例组数,接下来是 t 组测试用例。对于每组测试用例,一共 n+1 行。
第一行包含三个正整数 n,m,x,含义如题面所示。
之后 n 行,每行一个长度为 m 的仅含 01x?
的字符串。
对于每组测试用例,输出一行一个整数,代表最优策略下小杨的得分最多是多少。
输入 #1
2 3 3 1 000 111 01? 3 3 1 000 ?0? 01?
输出 #1
4 2
对于第二组测试用例,将 (2,1) 或者 (3,3) 变为 1 均是最优策略。
子任务编号 | 数据点占比 | t | n,m | x |
---|---|---|---|---|
1 | 30% | ≤5 | ≤10 | =1 |
2 | 30% | ≤10 | ≤500 | ≤30 |
3 | 40% | ≤10 | ≤500 | ≤300 |
对全部的测试数据,保证 1≤t≤10,1≤n,m≤500,1≤x≤300,保证所有测试用例 n×m 的总和不超过 2.5×10^5。
【题目大意】在一个n*m的矩阵中从(1,1)到(n,m)移动,只能向下或者向右移动,矩阵中有1和0,还有?,在移动的过程中尽可能的拿到1,可以将矩阵中的x个?修改成1,使得最后拿到的1尽可能的多。
【考纲知识点】动态规划
【解题思路】如果不考虑x,问题转换成为从(1,1)到(n,m)只能向下或者向右移动最多拿到多少个1。对于矩阵中的任意一点(i,j)只可能从(i-1,j)或者(i,j-1)移动过来。
状态设计:dp[i][j]表示到达位置(i,j)时可以获得的最大分数。
不难得到状态转移方程dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + (a[i][j] == ‘1’?1:0)。
考了加入x,还是只能向下或者向右移动,之前只有1对结果有贡献,现在?也对结果有贡献。由于x的限制,?不能无限制的修改成1,所以需要记录修改次数。设计状态时增加一维表示修改次数。
状态设计:dp[i][j][k]表示到达位置(i,j)时,已经修改了k个字符所能获得的最大分数。
如果a[i][j]是0或者1,正常转移,和不考虑x时的转移过程一致,如果a[i][j]是?,先考虑当前有没有修改次数,如果没有当前阶段拿到和1和上一阶段比较求最大值,如果有修改次数,,需要看之前修改转移的值是多少,求最大值。
当a[i][j] == 1时,dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k])+1,
当a[i][j] == 0时,dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]),
当a[i][j] == ?时,如果没有修改次数,dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]),
如果有修改次数,再考虑改或不改。
若修改当前节点为1,则有dp[i][j][k]=max(dp[i-1][j][k-1],dp[i][j-1][k-1])+1,
若不修改,则有dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]),
取以上情况的最大值即可,同时需要考虑,若k==x,则不可增加修改次数。
可以观察到每一行的计算只依赖于上一行的信息,第一维可以优化,故可以使用滚动数组对数组进行降维。
【参考程序】
本站题目仅供学习,GESP版权归CCF所有,如有侵权请联系删除。站长陈老师QQ及微信:208234。