6.19dp模拟

6.19dp模拟

概况

t1消耗时间过长,t2记录方案刷表法出大问题

A.NUMBER

思路

枚举两条路线分别到达每个点时的状态,只可能从上或左转移,所以枚举步数,三维解决,有可能是上上,上左,左上,左左

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
    
    
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){
    
    x=x*10+c-'0';c=getchar();}
	return x*f;
}
ll a[20][20],dp[100][20][20];
int main(){
    
    
	ll n=read(),x,y,num;
	while(scanf("%lld %lld %lld",&x,&y,&num)!=EOF){
    
    
		if(!num)break;
		a[x][y]=num;
	}
	for(int i=1;i<=2*n-1;i++){
    
    
		for(int x1=1;x1<=n;x1++){
    
    
			for(int x2=1;x2<=n;x2++){
    
    
				ll y1=i-x1+1,y2=i-x2+1;
				ll dp0=dp[i][x1][x2],
					dp1=dp[i-1][x1-1][x2-1],
					dp2=dp[i-1][x1-1][x2],
					dp3=dp[i-1][x1][x2-1],
					dp4=dp[i-1][x1][x2];
				if(x1==x2){
    
    
					dp[i][x1][x2]=max(dp0,max(dp1,max(dp2,max(dp3,dp4))))+a[x1][y1];
					continue;
				}
				dp[i][x1][x2]=max(dp0,max(dp1,max(dp2,max(dp3,dp4))))+a[x1][y1]+a[x2][y2];
			}
		}
	}
	printf("%lld",dp[2*n-1][n][n]);
	return 0;
}
/*
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
*/

时间管理大师

这道题时间做的太长,主要是陷入了思维误区,判断的时候出了问题,但是后来想出四维的正确思路后有因为多想了一些给否掉了,最后才想到了三维不会有重复的情况,1h33min

B.FLOWER

思路

三维dp,第一维枚举花瓶,第二维枚举花,第三维枚举当前花放在哪

代码

#include<bits/stdc++.h>
#define N 505
#define ll long long
using namespace std;
inline int read(){
    
    
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){
    
    x=x*10+c-'0';c=getchar();}
	return x*f;
}
ll dp[N][N],a[N][N],res=-2e9,res_num,pre[N][N];
void print(int i,int j){
    
    
	if(!i)return;
	print(i-1,pre[i][j]);
	printf("%lld ",j);
	return;
}
int main(){
    
    
	ll f=read(),v=read();
	memset(dp,-0x3f,sizeof(dp));
	for(int i=1;i<=f;i++)for(int j=1;j<=v;j++)a[i][j]=read();
	for(int i=0;i<=f;i++)dp[0][i]=0;
	for(int j=1;j<=v;j++)
		for(int i=1;i<=f;i++)
			for(int k=i-1;k<j;k++){
    
    
				if(dp[i][j]<dp[i-1][k]+a[i][j]){
    
    
					dp[i][j]=dp[i-1][k]+a[i][j];
					pre[i][j]=k;
				}
			}
	for(int i=1;i<=v;i++){
    
    
		if(res<dp[f][i]){
    
    
			res=dp[f][i];
			res_num=i;
		}
	}
	printf("%lld\n",res);
	print(f,res_num);
	return 0;
}
/*
3 5
7 23 -5 -24 16
5 21 -4 10 23
-21 5 -4 -20 20
*/

填表与刷表

刷表不行!,填表,行!

猜你喜欢

转载自blog.csdn.net/MuLaSaMe/article/details/118057951