矩阵

题目评测(借借DTT的私人题库)


 

题目描述

有一个n × m的矩阵,你从左上角走到右下角,只能向下和向右走。每个点上有一个重量v i,j 价值w i,j 的物品,你有一个容量为S的背包,经过一个点你可以将此点的物品放入背包,求最大能得到的价值。

输入

输入文件 matrix.in。
第一行三个数n, m, S。
下面n行,每行m个数,第i + 1行第j个数表示v i,j 。
下面n行,每行m个数,第i + n + 1行第j个数表示w i,j 。

输出

输出文件 matrix.out。
一行一个数表示最大的价值。

 

思路:
状态设置

f[j][k]

其中j代表列数,k代表此时背包的容量

转移方程

    f[j][k]=max(max(max(f[j][k-a[i][j].wei]+a[i][j].val,f[j][k]),f[j-1][k]),f[j-1][k-a[i][j].wei]+a[i][j].val);

//尽量别分开,因为f[j][k]的值会有所改变

输出

由于f[m][s]代表的不一定是最大值,所以我们不能直接输出f[m][s],我们还应该进行比较不同背包容量的值,而不用枚举不同位置的值,因为在DP中我们已经对其进行了处理,所以ans的输出也是要考虑的

样例输入

3 4 5
1 2 1 1
2 3 1 2
3 2 2 2
2 3 4 2
1 4 5 1
10 1 2 1

样例输出

14

代码
#include<bits/stdc++.h>
using namespace std;
int n,m,s;
int f[450][450];
int ans=0;
int scan()
{
    int as=0;
    char c=getchar();
    while(c<'0'||c>'9') c=getchar(); 
    while(c>='0'&&c<='9')
    {
        as=(as<<3)+(as<<1)+c-'0';
        c=getchar();
    }
    return as;
}
struct ss
{
    int val,wei;
}a[405][405];
int main()
{
    n=scan();
    m=scan();
    s=scan();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            a[i][j].wei=scan();
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            a[i][j].val=scan();
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int k=s;k>=0;k--)
            {
                if(k>=a[i][j].wei)
                {
                    f[j][k]=max(max(max(f[j][k-a[i][j].wei]+a[i][j].val,f[j][k]),f[j-1][k]),f[j-1][k-a[i][j].wei]+a[i][j].val);
                }
                else f[j][k]=max(f[j-1][k],f[j][k]);
            }
        }
    }
    for(int i=0;i<=s;i++)
    {
        ans=max(ans,f[m][i]);
    }
    cout<<ans;
    return 0;
}
View Code

 

posted @ 2019-01-27 18:39  K&S&T  阅读(235)  评论(0编辑  收藏  举报