Gym - 101502L L - Roads and Tracks dp

L. Roads and Tracks

time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

You are given a road of length n, that has m parallel tracks numbered from 1 to m.

You will start moving from the beginning of the road, and at track number 1. You want to pass the whole road (i.e. finish at position n + 1) and ending at any track.

If you are at position i and track number j, the cost to move forward to position i + 1 and track j is aij.

You can move between tracks at the same position. If you are at position i, it will take bij seconds to move from track j to j + 1 (or from track j + 1 to j). Note that moving between tracks does not change your position on the road.

Your task is to find what is the minimum cost required to pass the whole road starting from the beginning of the road and at track 1, and ending at any track. If there are multiple solutions, choose the one with minimum time.

Input

The first line contains an integer T, where T is the number of test cases.

The first line of each test case contains two integers n and m (1 ≤ n ≤ 25000) (2 ≤ m ≤ 25), where n is the length of the road, and m is the number of tracks.

Then n lines follow, each line contains m integers, where the jth integer in the ith line is the cost of passing through the road from position ito position i + 1 at track j (0 ≤ aij ≤ 109).

Then n lines follow, each line contains m - 1 integers, where the jth integer in the ith line is the number of required seconds to switch between tracks j and j + 1 at position i (0 ≤ bij ≤ 109)

Output

For each test case, print a single line containing two space separated integers x and y, where x is the minimum cost required to pass the road, and y is the minimum possible time to pass the road with the minimum cost x.

Example

input

1
5 3
1 1 1
2 2 2
2 1 3
1 7 1
2 1 2
2 1
1 3
1 2
1 8
2 1

output

6 4

Note

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use scanf/printfinstead of cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.


题意:题意难解释,我直接通俗的讲好了有n*m个格子,有个人要从(1,1)开始走,最终要走到第n+1行(不管从那一列走到这一行都可以),行间只能从上往下走,每条路都会有一个花费,一行中的列和列之间可相互走会有个时间(即从i+1列到i列还是从i列到i+1列都是同一个时间),问从(1,1)开始到达第n+1行的最小花费是多少,还要输出达到这个最小花费的最小时间。

做法:用dp来做,开数组dp[i][j][2],i和j即到当前第i行第j列,第三维的0表示花费,1表示时间。具体的见代码。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100005;
ll dp[25010][30][2],a[25010][30],b[25010][30];
ll n,m;
void read(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%lld",&a[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<m;j++)
            scanf("%lld",&b[i][j]);

}
int main(){
    int t;
    cin>>t;
    while(t--){
        memset(b,0,sizeof(b));
        read();
        memset(dp,125,sizeof(dp));
        dp[0][1][0]=0,dp[0][1][1]=0;
        for(int i=1;i<=n+1;i++){
            for(int j=1;j<=m;j++){
                dp[i][j][0]=dp[i-1][j][0]+a[i-1][j];//上一行的花费进行转移需要加上相应的时间
                dp[i][j][1]=dp[i-1][j][1];//上一行到这一行的时间直接转移
            }
            for(int j=2;j<=m;j++){
                if(dp[i][j][0]>dp[i][j-1][0]){//如果到第i行第j列的花费小于到第i行第j-1列的花费,则转移
                    dp[i][j][0]=dp[i][j-1][0];
                    dp[i][j][1]=dp[i][j-1][1]+b[i][j-1];
                }
                else if(dp[i][j][0]==dp[i][j-1][0]&&dp[i][j][1]>dp[i][j-1][1]+b[i][j-1]){
                    dp[i][j][1]=dp[i][j-1][1]+b[i][j-1];//如果到第i行第j列的花费等于到第i行第j-1列的花费
                }//,但时间上大于第i行第j-1列加上过来的时间的和,则转移
            }
            for(int j=m-1;j>=1;j--){//反向同理
                if(dp[i][j][0]>dp[i][j+1][0]){
                    dp[i][j][0]=dp[i][j+1][0];
                    dp[i][j][1]=dp[i][j+1][1]+b[i][j];
                }
                else if(dp[i][j][0]==dp[i][j+1][0]&&dp[i][j][1]>dp[i][j+1][1]+b[i][j]){
                    dp[i][j][1]=dp[i][j+1][1]+b[i][j];
                }
            }
        }
        printf("%lld %lld\n",dp[n+1][1][0],dp[n+1][1][1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/81606076