题解 【P1004 方格取数】
Create_Random · · 题解
看到题解里没有二维DP就补一发~
(有点沾沾自喜)
本蒟蒻的思路:
先跑一遍DP,
动态转移方程:
然后对经过的点进行删除,
再跑一遍DP,
将两次的值相加即可得到答案。
(有点暴力见谅)
贴代码(码丑见谅)
#include<bits/stdc++.h>
using namespace std;
int n;
bool b;
int a[20][20];
int f1[20][20];
int f2[20][20];
int ans,ans2;
int x,y,z;
int main()
{
cin>>n;
while(cin>>x>>y>>z)
{
if(!x&&!y&&!z)//x y z均为0时退出
{
break;
}
f1[x][y]=z;//
f2[x][y]=z;//直接赋值
}
for(int i=1;i<=n;i++)//DP求出第一条线路的最优解
{
for(int j=1;j<=n;j++)
{
f1[i][j]+=max(f1[i-1][j],f1[i][j-1]);//动态转移方程
}
}
ans+=f1[n][n];//存入第一条线路的最优解
ans2=ans;//防止ans被更改
while(ans2>0)//倒序寻找被取的数第一个出现的位置,为0时即为取完
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(f1[i][j]==ans2)//当被取的数出现时
{
ans2-=f2[i][j];//修改ans的值
f2[i][j]=0;//将这个点的值删为零
b=1;//打标记退出循环
break;
}
}
if(b==1)
{
b=0;//防止只能退出一次
break;
}
}
}
for(int i=1;i<=n;i++)//DP求出第二条线路的最优解
{
for(int j=1;j<=n;j++)
{
f2[i][j]+=max(f2[i-1][j],f2[i][j-1]);//动态转移方程
}
}
ans+=f2[n][n];//存入第二条线路的最优解
cout<<ans;
return 0;
}