捡金币

news/2024/11/30 1:30:02/

这里写图片描述
80分做法
DP本格子是从上个时间能够到达该格子的位置拓展出来的,可以闪现也可以步行(注意可以不动)
对这些状态取max即可
我们枚举时间,f[t][i][j][k]表示第t秒站在(i,j),已经用了k次闪现所获得的最大金币数
转移方程见代码,还是比较容易理解的。(对于 t 我是从零开始存的)
时间复杂度:T*C*W*n*n ≈ 5*10^7 ,60%,3s大概是能过的

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 1000000007
using namespace std;
int n,C,W,T,ans;
int s[101][26][26];
int f[101][26][26][151];//f[t][i][j][k]表示第t秒站在(i,j),已经用了k次闪现所获得的最大金币数 
int MAX(int &x,int y){if(y>x) x=y;}//取大 
bool judge(int x,int y)
{if(x<=n&&x>=1&&y<=n&&y>=1) return 1;return 0;
}
int main()
{scanf("%d%d%d%d",&n,&C,&W,&T);for(int i=1;i<=T;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) scanf("%d",&s[i][j][k]);for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[0][i][j][0]=s[1][i][j];for(int t=1;t<T;t++){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=0;k<=W;k++){MAX(f[t][i][j][k],f[t-1][i][j-1][k]+s[t+1][i][j]);//右走 MAX(f[t][i][j][k],f[t-1][i][j+1][k]+s[t+1][i][j]);//左走 MAX(f[t][i][j][k],f[t-1][i+1][j][k]+s[t+1][i][j]);//下走 MAX(f[t][i][j][k],f[t-1][i-1][j][k]+s[t+1][i][j]);//上走 MAX(f[t][i][j][k],f[t-1][i][j][k]+s[t+1][i][j]);//不动 for(int p=1;p<=C;p++)//闪现 {if(k-p>=0){if(judge(i,j-p*2)) MAX(f[t][i][j][k],f[t-1][i][j-p*2][k-p]+s[t+1][i][j]);if(judge(i,j+p*2)) MAX(f[t][i][j][k],f[t-1][i][j+p*2][k-p]+s[t+1][i][j]);if(judge(i-p*2,j)) MAX(f[t][i][j][k],f[t-1][i-p*2][j][k-p]+s[t+1][i][j]);if(judge(i+p*2,j)) MAX(f[t][i][j][k],f[t-1][i+p*2][j][k-p]+s[t+1][i][j]); } }} }for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=0;k<=W;k++)MAX(ans,f[T-1][i][j][k]);printf("%d",ans);return 0; 
}

100(优化闪现)
确定x,y中的一个状态,以另一个状态和k为横纵坐标会发现从上个状态闪现出来的是一个斜换行排列。闪现不用枚举c次,直接用单调队列维护最大值即可

#include <cstdio>
#define inf 1000000007
using namespace std;
int n,t,w,c;
int map[102][26][26];
int dp[2][26][26][151]; 
int l,r;
int dl[9999];
int qc[9999],cnt,tag;
int vis[99][99];
void init()
{l=1,r=0;dl[1]=-inf;dl[0]=inf;
} 
void max(int &x,int y)
{if(y>x) x=y;return;
}
inline int read()
{int data=0,w=1; char ch=0;while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();if(ch=='-') w=-1,ch=getchar();while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();return data*w;
}
void push(int x)
{dl[++r] = x;qc[r] = 1;dl[r+1] = -inf;while (dl[r] >= dl[r-1]){qc[r-1] += qc[r];dl[r-1] = dl[r];dl[r--] = -inf;}if (++cnt > c) if (--qc[l] == 0) dl[l++] = inf;
}
void min_c(int t)
{for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=0;k<=w;k++)dp[t][i][j][k]=-inf;
}
void Instantaneous_movement1(int t,int x)
{ tag++; for(int j=1;j<=n;j++)for(int k=0;k<=w;k++)if(vis[j][k]!=tag){init();int jj=j,kk=k;while(jj<=n&&kk<=w){vis[jj][kk]=tag;max(dp[t][x][jj][kk],dl[l]);push(dp[t^1][x][jj][kk]);jj+=2,kk++;}}tag++; for(int j=n;j>=1;j--)for(int k=0;k<=w;k++)if(vis[j][k]!=tag){init();int jj=j,kk=k;while(jj>=1&&kk<=w){vis[jj][kk]=tag;max(dp[t][x][jj][kk],dl[l]);push(dp[t^1][x][jj][kk]);jj-=2,kk++;}}   
}
void Instantaneous_movement2(int t,int y)
{ tag++; for(int i=1;i<=n;i++)for(int k=0;k<=w;k++)if(vis[i][k]!=tag){init();int ii=i,kk=k;while(ii<=n&&kk<=w){vis[ii][kk]=tag;max(dp[t][ii][y][kk],dl[l]);push(dp[t^1][ii][y][kk]);ii+=2,kk++;}}tag++; for(int i=n;i>=1;i--)for(int k=0;k<=w;k++)if(vis[i][k]!=tag){init();int ii=i,kk=k;while(ii>=1&&kk<=w){vis[ii][kk]=tag;max(dp[t][ii][y][kk],dl[l]);push(dp[t^1][ii][y][kk]);ii-=2,kk++;}}
}
void walk(int t,int time)
{for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)for(int k=0;k<=w;++k){max(dp[t][i][j][k],dp[t^1][i-1][j][k]);max(dp[t][i][j][k],dp[t^1][i+1][j][k]);max(dp[t][i][j][k],dp[t^1][i][j-1][k]);max(dp[t][i][j][k],dp[t^1][i][j+1][k]);max(dp[t][i][j][k],dp[t^1][i][j][k]);dp[t][i][j][k]+=map[time][i][j];}
}
int main()
{

http://www.ppmy.cn/news/455240.html

相关文章

捡点我的职业生涯

十五年前&#xff0c;你或许还不懂爱情&#xff0c;看Jack和Rose执手相看泪眼&#xff0c;只是蒙胧的心痛。十五年后&#xff0c;你会和谁一起走进影院&#xff0c;更会和谁一起&#xff0c;走到生命终点。 十五年前&#xff0c;我还不太懂技术&#xff0c;凭兴趣玩着C语言。十…

捡的

说好的教我一个简单的JS&#xff0c;时间一到立马陪嫂子打电话去了。哥&#xff0c;你果然是伯母捡来的。。。 转载于:https://www.cnblogs.com/bingg/p/5313851.html

捡到iphone6怎么解锁_捡到的iPhone被锁了怎么办

Apple ID 密码是用户要下载软件游戏时所需要的账户密码。一般卖家会帮用户 装些软件&#xff0c;但那是卖家的账户&#xff0c;用户不知道密码就不能自己下载软件。而且 IPHONE 手机不允许同一个机子出现 2 个账户下载的软件。所以最好的办法是 自己创建一个账户。 但自己下载前…

捡钱包了

taobao上看到一块inno3D的6600gt agp卖&#xff0c;卖主说不知怎么的有一天就点不亮了&#xff0c;我看了一下大图&#xff0c;原件没有损坏的迹象&#xff0c;反正也就15块钱&#xff0c;就买了&#xff0c;想拼一下rp和技术~ 拿回来先清洗&#xff0c;能拆的都拆掉&#xff0…

#捡石子

#捡石子 题&#xff1a;有一堆石子共有N个。A B两个人轮流拿&#xff0c;A先拿。每次最少拿1颗&#xff0c;最多拿K颗&#xff0c;拿到最后1颗石子的人获胜。假设A B都非常聪明&#xff0c;拿石子的过程中不会出现失误。给出N和K&#xff0c;问最后谁能赢得比赛。 例如N 3&…

作为一名帝都的程序员,我为什么去捡垃圾?

自从我在副业收入是我做程序媛的3倍&#xff0c;工作外的B面人生是怎样的&#xff1f;这篇博客评论之后&#xff0c;我回答的评论点赞数飙升到第一&#xff1a; 我说的是实话&#xff0c;大学以前&#xff0c;我确实将我所在的小城市都搜罗了一遍&#xff0c;自从读完大学到现…

1850. 捡苹果

1850. 捡苹果 Alice 和 Bob 在一个漂亮的果园里面工作&#xff0c;果园里面有N棵苹果树排成了一排&#xff0c;这些苹果树被标记成1 - N号。 Alice 计划收集连续的K棵苹果树上面的所有苹果&#xff0c;Bob计划收集连续的L棵苹果树上面的所有苹果。 Alice和Bob选择的区间不可以重…

【趣题】几堆石子轮流捡,谁捡到最后的石子算输的游戏

一 题目描述 有三堆石子&#xff0c;分别为7,5,3个每堆&#xff0c;两个人轮流进行如下操作&#xff1a; 选择一堆&#xff08;石子数不为0&#xff09;&#xff1b; 从这堆石子中取走至少一个&#xff0c;至多全部的石子&#xff1b; 直到有人拿走最后一颗石子&#xff0c;该…