NOIP2008洛谷P1006传纸条

题意中文不再赘述

思路:我们考虑一个dp[i][[j][k][e],表示从两个纸条分别位于(i,j)(k,e)的时候的最大值,我们发现它由两个大状态,四个小状态转移,就是dp[i-1][j][k-1][e],dp[i-1][j][k][e-1],dp[i][j-1][k-1][e],dp[i][j-1][k][e-1],这四个情况分别代表从两个位置转到下两个位置,根据题意,纸条只会向下或向右传,所以就是这四个状态取max然后加上c[i][j]+c[k][e],也就是新位置的权值,然后会发现,可能会出现两个人新位置的重合,所以要减去一个c[i][j],因为相同位置不传,也就是没有权值

代码

#include
#include
#include
#include
#include
using namespace std;
const int M=60;
int n,m;
int map[M][M];
int f[M][M][M][M];
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    for (int k=1;k<=m;k++)
    scanf("%d",&map[i][k]);
    for (int i=1;i<=n;i++)
    for (int j=1;j<=m;j++)
    for (int k=1;k<=n;k++)
    for (int e=1;e<=m;e++)
    {
        f[i][j][k][e]=max(max(f[i-1][j][k-1][e],f[i-1][j][k][e-1]),max(f[i][j-1][k-1][e],f[i][j-1][k][e-1]))+map[i][j]+map[k][e];
        if (i==k&&e==j) f[i][j][k][e]-=map[i][j];
    }
    cout<

还有一份学长给的,貌似是转化成两个数字三角形,求两条最大数字和

//By Acer.mo
#include
#include
using namespace std;
int n,m,i,j,k;
int f[500][500][500]={0};
int map[500][500];
int main()
{
    cin>>n>>m;
    for (i=1;i<=n;i++)
     	for (j=1;j<=m;j++)
     	 	cin>>map[i][j];
    for (k=1;k

你可能感兴趣的:(动态规划)