昨天由于种种原因没有写题目,感觉自己的效率真的是好捉急。
虽然仅仅是开始,但是也一样不应该有“还是慢慢渐入佳境吧” 这种的想法么2333
Time Limit: 3 second(s) | Memory Limit: 32 MB |
Its year 2200, planet Earth is out of resources and people are relying on the resources from other planets. There are several Refining Companies who collect these resources from other planets and bring them back to Earth. The task may sound simple, but in reality it's a challenging job. The resources are scattered and after collecting them, they have to be taken to a place where they can be refined. Since some minerals are extremely dangerous, the whole process should be done very carefully. A single tiny mistake can cause a massive explosion resulting in a huge loss.
You work in such a company who collects Uranium and Radium from planet Krypton. These minerals are used for generating powers. For simplicity you have divided planet Krypton into cells that form a matrix of m rows and n columns, where the rows go from east to west and the columns go from north to south. Your advanced mine detector has detected the approximate amount of Radium and Uranium in each cell. Your company has built two refining factories, one in West and the other in North. The factory in North is used to refine Radium and the factory in West is used to refine Uranium. Your task is to design the conveyor belt system that will allow them to mine the largest amount of minerals.
There are two types of conveyor belts: the first moves minerals from east to west, the second moves minerals from south to north. In each cell you can build either type of conveyor belt, but you cannot build both of them in the same cell. If two conveyor belts of the same type are next to each other, then they can be connected. For example, the Radium mined at a cell can be transported to the Radium refinement factory via a series of south-north conveyor belts.
The minerals are very unstable, thus they have to be brought to the factories on a straight path without any turns. This means that if there is a south-north conveyor belt in a cell, but the cell north of it contains an east-west conveyor belt, then any mineral transported on the south-north conveyor belt will be lost. The minerals mined in a particular cell have to be put on a conveyor belt immediately; in the same cell (thus they cannot start the transportation in an adjacent cell). Furthermore, any Radium transported to the Uranium refinement factory will be lost, and vice versa.
Your program has to design a conveyor belt system that maximizes the total amount of minerals mined, i.e., the sum of the amount of Radium transported to the Radium refinery and the amount of Uranium to the Uranium refinery.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case begins with a blank line and two integers: m - the number of rows, and n - the number columns (1 ≤ m, n ≤ 500). The next m lines describe the amount of Uranium that can be found in the cells. Each of these m lines contains n integers. The first line corresponds to the northernmost row; the first integer of each line corresponds to the westernmost cell of the row. The integers are between 0 and 1000. The next m lines describe in a similar fashion the amount of Radium found in the cells. Data set is huge, so use faster i/o methods.
Output
For each case of input you have to print the case number and the maximum amount of minerals you can collect.
Sample Input | Output for Sample Input |
2
4 4 0 0 10 9 1 3 10 0 4 2 1 3 1 1 20 0 10 0 0 0 1 1 1 30 0 0 5 5 5 10 10 10
2 3 5 10 34 0 0 0 0 0 0 50 0 0 | Case 1: 98 Case 2: 50 |
Note
Dataset is huge. Use faster I/O methods.
题意:就是两个N*M的矩阵表示两种不同资源,其中一种资源需要从下向上运,运到整个矩阵顶端,另一种资源从右向左运,运到矩阵的最左端。每一条运输线的所运送的资源就是该运输线上所有该种有效资源之和。需要注意的是从下往上运的资源如果被从右向左运的运输线阶段,则阶段点以下资源全部无效。对于从右向左运的资源也是同理。最后求最多可以获得多少资源(两种资源和)。
嗯 初见这个题目的时候被略低的通过人数吓到Orz~ 然后就把这个题目想的挺难的 总体思路一开始就凭着感觉是dp,但也犯过一个超级低级的错误。
然后我们说明黄色为需要向上运输资源的运输线。可以知道下左图所示的情况是非法的XD,因为其一定不比下右图的决策优。
因此我们知道 向上运输资源的运输线 从右到左的运输线长度是递减的。
而除开作为向上运输资源运输线的部分,剩余部分应该全部作为向左运输资源的运输线。
到此为止 动态规划状态可以清晰得到f[i][j]表示 第j列的运输线长度为i时,目前所有有效资源的总和。(同时需要注意的一点是因为在该决策下不会出现截断的情况,因此有效资源一定是最后可以运输到终点的资源)
而转移方程也是 min(f[i][j]+sum_radim+sum_urm,f[p][j-1]) (p<=i)-------> f[p][j-1]
当然还需要做少部分预处理工作不在这里赘述。
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int dp[505][505];
int urmx[505][505];
int ramx[505][505];
void gao(int cas){
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
memset(urmx,0,sizeof(urmx));
memset(ramx,0,sizeof(ramx));
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&urmx[i][j]);
for (int i=n-1;i>=0;i--)
for (int j=0;j<=m;j++)
urmx[i][j]=urmx[i+1][j]+urmx[i][j];
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&ramx[i][j]);
for (int i=1;i<=n;i++)
for (int j=0;j<=m;j++)
ramx[i][j]=ramx[i-1][j]+ramx[i][j];
for (int i=0;i<=n;i++){
int tmp=(i==n)?(0):(urmx[i+1][m]);
dp[i][m]=ramx[i][m]+tmp;
}
for (int col=m;col>=1;col--)
for (int row=0;row<=n;row++)
for (int nex=0;nex<=row;nex++){
int tmp=(nex==n)?(0):(urmx[nex+1][col-1]);
dp[nex][col-1]=max(dp[nex][col-1],dp[row][col]+ramx[nex][col-1]+tmp);
}
int ans=0;
for (int i=0;i<=n;i++)
if (dp[i][0]>ans)
ans=dp[i][0];
printf("Case %d: %d\n",cas,ans);
}
int main(){
int cas;
scanf("%d",&cas);
for (int i=1;i<=cas;i++)
gao(i);
}
这个代码感觉效率很低啊 跑了2.5s左右 已经逼近时限了。因此我在想这题是否有什么优化方法可以进一步降低复杂度的。凭着感觉不负责任的说,说不定用斜率优化相关的优化可以搞出来,但是既然过了对吧,你们懂的!
然后就这样吧