CF EDU 128 E - Moving Chips
E - Moving Chips
线性dp
一开始想贪心,但 wa 在1101个点。。。
正解是 dp
首先根据一点贪心的思想,若最后在第 列,那第 列左边的向右走,第 列右边的向左走肯定是最优的
: 最终在 ,第 列左边的走到这个位置的步数
:最终在 ,第 列右边的走到这个位置的步数
注意均不包括第 列的代价
转移:
注意转移是从左右两边第一个 * 开始转移,没有 * 的地方是没有代价的
若从上一列的不同行过来,一定需要两步
若从上一列的相同行过来,如果 这一列的另一个元素没有 , 则需要一步;若有 , 则需要把这个星移到 需要多一步
答案为
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
void solve()
{
int n;
cin >> n;
string s[2];
cin >> s[0] >> s[1];
int ans = 1e9;
int l, r;
for (int i = 0; i < n; i++)
{
if (s[0][i] == '*' || s[1][i] == '*')
{
l = i;
break;
}
}
for (int i = n - 1; i >= 0; i--)
{
if (s[0][i] == '*' || s[1][i] == '*')
{
r = i;
break;
}
}
int pre[2][n], suf[2][n];
for (int i = 0; i <= 1; i++)
for (int j = 0; j < n; j++)
pre[i][j] = suf[i][j] = 0;
for (int j = l + 1; j <= r; j++)
for (int i = 0; i <= 1; i++)
pre[i][j] = min(pre[1 - i][j - 1] + 2, pre[i][j - 1] + 1 + (s[1 - i][j - 1] == '*'));
for (int j = r - 1; j >= l; j--)
for (int i = 0; i <= 1; i++)
suf[i][j] = min(suf[1 - i][j + 1] + 2, suf[i][j + 1] + 1 + (s[1 - i][j + 1] == '*'));
for (int i = 0; i <= 1; i++)
{
for (int j = l; j <= r; j++)
{
ans = min({
ans,
pre[i][j] + suf[i][j] + (s[1 - i][j] == '*')
});
}
}
cout << ans << endl;
}
int main()
{
int T;
cin >> T;
while (T--)
solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!