数字三角形

开始好好学动态规划了~

https://www.acwing.com/problem/content/1017/

数字三角形,找好转移关系即可

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t,r,c,a[110][110];
int main(){
	cin>>t;
	memset(a,0,sizeof a);
	while(t--){
		cin>>r>>c;
		for(int i=1;i<=r;i++)
			for(int j=1;j<=c;j++)cin>>a[i][j],a[i][j]+=max(a[i-1][j],a[i][j-1]);	
		cout<<a[r][c]<<endl;
	}
return 0;}

https://www.acwing.com/problem/content/1020/

可以把边上先预处理一下来避免分类讨论

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[110][110];
int main(){
	cin>>n;
	memset(a,0,sizeof a);
	for(int i=0;i<=n;i++)a[i][0]=a[0][i]=110;a[1][0]=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)cin>>a[i][j],a[i][j]+=min(a[i-1][j],a[i][j-1]);
cout<<a[n][n]<<endl;
return 0;}

https://www.acwing.com/problem/content/1029/

这个题思维量较大,题意为走两次矩阵,算最大值之和,第一次如果走过某点,第二次走过时就没有加

和,首先贪心地先走一遍,更新矩阵,再走一遍的方法是不行的

所以我们发现走的第一遍存在后向性,于是我们两次同时处理:

总共走k步,到达(i1,j-i1) (i2,k-i2) 两点

如果i1==i2,那么肯定是同一点,同一点上的数只能取一次

反之如果i1!=i2,可以取两点的值之和

转移可以通过 (右,右)(右,下),(下,右),(下,下)四种方法得到

代码如下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,a[110][110],f[110][110][220],x,y,z;
int main(){
cin>>n;
memset(a,0,sizeof a);
memset(f,0,sizeof f);
while(cin>>x>>y>>z,x||y||z){
	a[x][y]=z;
} 

for(int k=2;k<=n*2;k++){
	for(int i1=1;i1<=n;i1++){
		for(int i2=1;i2<=n;i2++){
			if(k-i1>n||k-i2>n||k-i1<=0||k-i2<=0)continue;
			int t=a[i1][k-i1];
			if(i1!=i2)t+=a[i2][k-i2];
			f[i1][i2][k]=max(f[i1][i2][k],f[i1][i2][k-1]+t);
			f[i1][i2][k]=max(f[i1][i2][k],f[i1-1][i2][k-1]+t);
			f[i1][i2][k]=max(f[i1][i2][k],f[i1][i2-1][k-1]+t);
			f[i1][i2][k]=max(f[i1][i2][k],f[i1-1][i2-1][k-1]+t);
		}
	}
}
cout<<f[n][n][2*n]<<endl;
return 0;}

posted @ 2022-03-28 20:26  misasteria  阅读(89)  评论(0编辑  收藏  举报