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
*/
填表与刷表
刷表不行!,填表,行!