algorithm_2024/README.md
2024-10-17 21:30:20 +08:00

112 lines
3.5 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# algorithm_2024
algorithm_2024
## 错题本
### Luogu某题
#### 数组越界导致变量异常更改
### [OJ4980:拯救行动](http://noi.openjudge.cn/ch0205/4980/)
#### 未考虑无答案(特殊情况)时输出
#### 优先队列是从大到小排序重载运算符时需反向或者std::greater
```cpp
for(ll i{0};i<4;i++){
const Point next {status.now.x+to_next[i][0],status.now.y+to_next[i][1]};
if(vis[next.x][next.y])continue;
const auto nextchar = [&next]()->char{return map[next.x][next.y];};
ll cost {1};
if(next.x>h || next.x<=0 || next.y > w || next.y<=0
|| nextchar()=='#')continue;
if(nextchar()=='x')cost++; // 因为这里有可能会遇到士兵会改变最优解顺序要使用priority_queue
const Status next_status {next,status.step+cost};
vis[next_status.now.x][next_status.now.y] = true;
q.push(next_status);
}
```
```cpp
struct Status{
Point now;
ll step;
bool operator<(const Status &that)const noexcept{
return this->step > that.step;
}
};
std::priority_queue<Status> q;
```
### [P1330](https://www.luogu.com.cn/problem/P1330)
#### BFS时注意初始化一开始的去重数组
```cpp
void bfs(){
for(ll i{1};i<=n;i++){
color_sum[1]=color_sum[2]=0;
if(vis[i])continue;
q.push(i);
set_color(i, 1);
vis[i]=true; // 注意初始化错误
while(!q.empty()){
```
### [P3957](https://www.luogu.com.cn/problem/P3957)
#### 初始状态依赖已走过的部分时注意起始点状态
```cpp
for(ll coin{0};coin<=(points[n].posit-d);++coin){
for(ll i{0};i<max_n;i++)dp[i]=ll_min;
dp[0]=0; // 注意第0个点是能到达的reachable
```
#### 非最优解时注意骗分卡时间
```cpp
const ll max_coin{(ll)1e5+5};//d+g = x[n] -> g = x[n]-d我的推导是这样的但是错了必须将max_coin设置为1e5+5也就是s[i]最大值,注意超时问题,可以自己生成样例测试
ll l{0},r{max_coin},ans{ll_max};
while(l<=r){
ll mid{(l+r)/2};
const bool check_ret{check(mid)};
if(check_ret){
ans = mid;
r=mid-1;
}else{
l=mid+1;
}
}
```
### [P7414](https://www.luogu.com.cn/problem/P7414)
#### 区间DP思路
```cpp
/*
区间动态规划解题步骤:
1.根据问题推测dp[i][j]的含义
问题将第1个到第个位置涂上指定颜色的最小次数
dp[i][j]的含义将第i个到第j个位置涂上指定颜色的最小次数
2.根据规则推出dp[i][j]的状态转移公式
在i-j之间找一个中间值k将i-j这一段分成两段i-k和k+1~j
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
3.边界问题比如设定dp[0][0],dp[0][j],dp[i][0]初始值)
dp[i][j]=dp[i][j-1]+(a[i]!=a[j]);
dp[i][i]=1;
*/
```
### [oj8782](http://noi.openjudge.cn/ch0206/8782)
```cpp
/*
区间动态规划解题步骤:
1.根据问题推测dp[i][j]的含义
问题长度为N的数字串要求选手使用K个乘号将它分成K+1个部分
dp[i][j]的含义长度为i的数字串要求选手使用j个乘号将它分成j+1个部分
2.根据规则推出dp[i][j]的状态转移公式
在1-i之间找一个中间值k将1-i这一段分成两段1-k(有j-1个乘号)和k+1~i(没有乘号)
dp[i][j]=max(dp[i][j],dp[k][j-1]*num[k+1][i]);
3.边界问题比如设定dp[0][0],dp[0][j],dp[i][0]初始值)
num[i][j]
*/
```