luoguP1174 打砖块
solution
本来直接写的背包,结果是错误的。
因为最后一枪0->-1->0是不行的。
所以从前到后一次背包,从后到前一次背包。
然后枚举在哪里打的最后一枪。
除了最后一枪都没有什么顺序关系
code
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define int long long
using namespace std;
const int _=307;
// const int mod=1e9+7;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int a[_][_],b[_][_];
int g[_][_],f[_][_],sum_a[_][_],sum_b[_][_];
void solve() {
int n=read(),m=read(),shoot=read(),ans=0;
for(int i=n;i>=1;--i) FOR(j,1,m) {
int x;char s;
cin>>x>>s;
a[i][j]=x;
b[i][j]=(s=='N');
}
FOR(i,1,n) FOR(j,1,m) {
sum_a[i][j]=sum_a[i-1][j]+a[i][j];
sum_b[i][j]=sum_b[i-1][j]+b[i][j];
}
memset(f,-0x3f,sizeof(f));
memset(g,-0x3f,sizeof(g));
f[0][shoot]=g[m+1][shoot]=0;
FOR(i,1,m) FOR(j,0,n) FOR(k,1,shoot) {
if(k+sum_b[j][i]>shoot) continue;
f[i][k]=max(f[i][k],f[i-1][k+sum_b[j][i]]+sum_a[j][i]);
ans=max(ans,f[i][k]);
}
for(int i=m;i>=1;--i) FOR(j,0,n) FOR(k,1,shoot) {
if(k+sum_b[j][i]>shoot) continue;
g[i][k]=max(g[i][k],g[i+1][k+sum_b[j][i]]+sum_a[j][i]);
ans=max(ans,g[i][k]);
}
FOR(i,1,m) FOR(j,0,n) FOR(k,1,shoot) {
if(b[j][i]&&k-sum_b[j][i]>=0&&shoot-(k-sum_b[j][i])>0) {
ans=max(ans,sum_a[j][i]+f[i-1][k]+g[i+1][shoot-(k-sum_b[j][i])]);
}
}
cout<<ans<<"\n";
}
signed main() {
#ifdef ONLINE_JUDGE
#else
freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
#endif
int T=read();
while(T--) {
solve();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】