插头动态规划

This commit is contained in:
LittleSheep 2024-05-26 14:30:41 +08:00
parent 4e3b93b7c2
commit 89365408c7
2 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,32 @@
#include <climits>
#include <iostream>
#include <iterator>
#include <set>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
int arr[n];
for (int i = 0; i < n; i++)
cin >> arr[i];
multiset<int> m;
int result = INT_MAX;
for (int i = 0; i < n - k + 1; i++) {
if (i == 0) {
for (int j = i; j <= i + k - 1; j++)
m.insert(arr[j]);
} else {
m.erase(arr[i - 1]);
m.insert(arr[i + k - 1]);
}
int count = 0;
auto middle_ptr = m.begin();
advance(middle_ptr, m.size() / 2);
for (const auto &element : m) {
count += abs(element - *middle_ptr);
}
result = min(result, count);
}
printf("%d\n", result);
}

156
plug-dp/main.cc Normal file
View File

@ -0,0 +1,156 @@
#include <algorithm>
#include <cstring>
#include <iostream>
#define ll long long
#define mo 590027
using namespace std;
int n, m, mapx[20][20] = {0}, endx, endy;
ll all_ans = 0, dp[2][600000] = {0};
int bits[28] = {0};
int state[2][600000] = {0}, tots[2] = {0};
int pre = 1, cnt = 0;
struct hash_table {
int pre, to;
} idx[600000] = {0};
int ptr[600000] = {0}, at = 0;
inline void readit() {
cin >> n >> m;
char cht = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
mapx[i][j] = 1;
endx = i;
endy = j;
}
}
inline void init_bits() {
for (int i = 1; i <= 25; i++)
bits[i] = (i << 1);
}
inline void hah(int sta, ll val) {
int key = sta % mo;
for (int prex = ptr[key]; prex; prex = idx[prex].pre)
if (state[cnt][idx[prex].to] == sta) {
dp[cnt][idx[prex].to] += val;
return;
}
tots[cnt]++;
state[cnt][tots[cnt]] = sta;
dp[cnt][tots[cnt]] = val;
idx[++at].pre = ptr[key];
idx[at].to = tots[cnt];
ptr[key] = at;
}
inline void calc_dp() {
tots[cnt] = 1;
dp[cnt][1] = 1;
state[cnt][1] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= tots[cnt]; j++)
state[cnt][j] <<= 2; //!!!
for (int j = 1; j <= m; j++) {
at = 0;
memset(ptr, 0, sizeof ptr); // clear hash_table
swap(pre, cnt); // rolling
tots[cnt] = 0; // clear state counter
int nowsta, is_d, is_r;
ll nowans;
for (int k = 1; k <= tots[pre]; k++) {
nowsta = state[pre][k], nowans = dp[pre][k]; // get previous
// state&answer
is_d = (nowsta >> bits[j]) % 4,
is_r = (nowsta >> bits[j - 1]) % 4; // get current plugs
if (!mapx[i][j]) // case 0
{
if ((!is_d) && (!is_r))
hah(nowsta, nowans);
}
else if ((!is_d) && (!is_r)) // case 1
{
if (mapx[i + 1][j] && mapx[i][j + 1])
hah(nowsta + (1 << bits[j - 1]) + 2 * (1 << bits[j]), nowans);
}
else if ((!is_d) && is_r) // case 2
{
if (mapx[i + 1][j])
hah(nowsta, nowans); // go down
if (mapx[i][j + 1])
hah(nowsta - is_r * (1 << bits[j - 1]) + is_r * (1 << bits[j]),
nowans); // go right
}
else if (is_d && (!is_r)) // case 3
{
if (mapx[i][j + 1])
hah(nowsta, nowans); // go right
if (mapx[i + 1][j])
hah(nowsta - is_d * (1 << bits[j]) + is_d * (1 << bits[j - 1]),
nowans); // go down
}
else if (is_d == 1 && is_r == 1) // case 4
{
int count = 1;
for (int l = j + 1; l <= m; l++) {
if ((nowsta >> bits[l]) % 4 == 1)
count++;
else if ((nowsta >> bits[l]) % 4 == 2)
count--;
if (!count) {
hah(nowsta - (1 << bits[l]) - (1 << bits[j]) - (1 << bits[j - 1]),
nowans);
break;
}
}
}
else if (is_d == 2 && is_r == 2) // case 5
{
int count = 1;
for (int l = j - 2; l >= 0; l--) {
if ((nowsta >> bits[l]) % 4 == 1)
count--;
else if ((nowsta >> bits[l]) % 4 == 2)
count++;
if (!count) {
hah(nowsta - 2 * (1 << bits[j]) - 2 * (1 << bits[j - 1]) +
(1 << bits[l]),
nowans);
break;
}
}
}
else if (is_d == 1 && is_r == 2) // case 6
hah(nowsta - 2 * (1 << bits[j - 1]) - (1 << bits[j]), nowans);
else if (is_r == 1 && is_d == 2) // case 7
if (i == endx && j == endy)
all_ans += (ll)nowans;
}
}
}
}
int main() {
readit();
init_bits();
calc_dp();
// 无方向不用乘 2
cout << all_ans * 2 << endl;
return 0;
}