摘花生
题目:摘花生
思路:闫氏DP法
状态表示:f(i,j)
集合:f(i,j)表示从(1,1)到(i,j)的路径的集合
属性:max
状态计算:
从上面走过来,对应着f(i-1,j)
从左边走过来,对应着f(i,j-1)
最后的状态计算方程就是f(i,j)=max{f(i-1,j),f(i,j-1)}+w(i,j)
答案就是f(n,m)
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int f[N][N],w[N][N];
int n,m,T;
int main()
{
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>w[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
f[i][j]=max(f[i-1][j],f[i][j-1])+w[i][j];
cout<<f[n][m]<<endl;
}
}
数字三角形
题目:数字三角形
思路:闫氏DP分析法
状态表示f(i,j)
集合:从(i,j)到最后一层(第一层)的所有方案
属性:max
状态计算
这条路径可以从(i+1,j)走上来,即f(i+1,j)+w(i,j)
也可以从(i+1,j+1)走上来,即f(i+1,j+1)+w(i,j)
状态计算方程是f(i,j)=max{f(i+1,j),f(i+1,j+1)}+w(i,j)
所有答案就是f(1,1)
#include <bits/stdc++.h>
using namespace std;
const int N=510;
int f[N][N],w[N][N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
cin>>w[i][j];
for(int i=1;i<=n;i++)
f[n][i]=w[n][i];
for(int i=n-1;i;i--)
for(int j=1;j<=i;j++)
f[i][j]=max(f[i+1][j],f[i+1][j+1])+w[i][j];
cout<<f[1][1];
}
最低通行费
题目:最低通行费
思路:和摘花生问题差不多,区别在于最大值改为了最小值,依旧用闫氏DP分析法
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int f[N][N],w[N][N];
int n;
int main()
{
memset(f,1e6,sizeof f);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>w[i][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(i==1&&j==1)
f[i][j]=w[i][j];
else
f[i][j]=min(f[i-1][j],f[i][j-1])+w[i][j];
}
cout<<f[n][n];
}