P1174 打砖块
链接
https://www.luogu.com.cn/problem/P1174
思路
刚开始的思路:设置dp[i][j]:前i列使用了j颗子弹,那么递推dpi,j=max(dpi,j,dpi-1,k+maxj-k),然后统计在第i列使用了j-k颗子弹会多出来多少颗,把这些遍历加到前面,见代码。喜提70pts。但是搞不懂哪里错了。
看了评论区的dp:
70pts代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
using namespace std;
const int N = 1e3 + 10;
int n, m, k;
int mp[N][N];
int has[N][N];
int dp[N][N];
//dp[i][j]:前i列用了j发子弹,然后利用前缀和
void init()
{
for (int j = 1; j <= m; j++)
for (int i = n; i > 0; i--)
mp[i][j] += mp[i + 1][j],
has[i][j] += has[i + 1][j];
}
signed main()
{
IOS;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> mp[i][j];
char x; cin >> x;
has[i][j] = (x == 'Y')?1:0;
}
init();
for (int j = 1; j <= k; j++)
{
int now = min(j, n) ;
int cal = min(has[n - now + 1][1] + now, n);
dp[1][j] = mp[n - cal + 1][1];
}
for (int i = 2; i <= m; i++)
for (int j = 1; j <= k; j++)
{
for (int l = 0; l <= j; l++)
{
int now = min(j - l, n);
int add = has[n - now + 1][i];
for (int ik = 0; ik <= add; ik++)
{
int cal2= min(add - ik + now, n);
dp[i][j] = max(dp[i][j], dp[i - 1][min(l + ik,k)] + mp[n - cal2 + 1][i]);
}
}
}
cout << dp[m][k];
return 0;
}
AC代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define int long long
using namespace std;
int n, m, k;
bool c[205][205];
char x;
int a[205][205];
int dy[205][405], dn[205][405], dpn[205][405], dpy[205][405];
signed main() {
IOS;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j] >> x;
if (x == 'Y') c[i][j] = 1;
}
}
for (int j = 1; j <= m; j++) {
int tot = 0;
for (int i = n; i >= 1; i--) {
if (c[i][j] == 1) dy[j][tot] += a[i][j];
else {
tot++;
dn[j][tot] = dy[j][tot - 1] + a[i][j];
dy[j][tot] = dn[j][tot];
}
}
}
for (int i = 1; i <= m; i++) {
for (int j = 0; j <= k; j++) {
for (int l = 0; l <= min(j, n); l++) {
dpy[i][j] = max(dpy[i][j], dpy[i - 1][j - l] + dy[i][l]);
if (l != 0) dpn[i][j] = max(dpn[i][j], dpy[i - 1][j - l] + dn[i][l]);
if (j != l) dpn[i][j] = max(dpn[i][j], dpn[i - 1][j - l] + dy[i][l]);//如果不是所有的子弹都投到j列
}
}
}
cout<<dpn[m][k];
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效