廣搜或深蒐會超時,我用優化過的廣搜超時了。
設原陣列的為
x x
,全排列中的某個陣列為
y' role="presentation">y
y存在這樣的事實:對於原陣列
x x
的全排列,對每一種排列都可以經過操作2變成目標陣列
y' role="presentation">y
y。這樣能夠覆蓋所有情況,保證能得到最優值。 設z
z
為x' role="presentation">x
x的某個排列方式,需要計算從
x x
變成y' role="presentation">y
y的最少交換次數。設z[
i]z [i
]是陣列的第
i i
個元素,它在
x' role="presentation">x
x中位置為po
s[z[
i]] pos
[z[i
]]
,那麼可以這樣計算交換次數:
int cnt = 0;
for(int i = 0; i
< n; i++)
}
但是,當陣列中存在重複元素時這個**會出現bug。此時需要用下標來唯一標識每個元素,用i來代表第i個元素。
計算完了交換次數,還要計算加減1的次數:
for(int i = 0; i < n; i++)
細節處理見**
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define inf 0x3f3f3f3f
#define pii pair
typedef
long
long ll;
const
int maxn = 10 + 5;
int n;
char a[maxn], b[maxn];
int c[maxn], d[maxn], x[maxn];
int main()
int w[maxn], pos[maxn];
int ret = inf;
do for(int i = 0; i < n; i++)
}for(int i = 0; i < n; i++)
ret = min(ret, cnt);
} while(next_permutation(x, x + n));
printf("%d\n", ret);
}return
0;}
如有不當之處歡迎指出! hihocoder 1520 古老數字
時間限制 20000ms 單點時限 2000ms 記憶體限制 256mb 小hi有一張紙條,上面寫著乙個長度為n的整數。由於年代過於久遠,其中有些位置已經看不清了,我們用 來代替這個位置。小hi印象中記得這個數字除以x的餘數為y,他想知道這個數最小可能是多少?注意這個整數的首位不能是0,除非它本身等...
HiHoCoder1033交錯和 數字dp
給定乙個數 x,設它十進位制展從高位到低位上的數字依次是 a0 a1,an 1 定義交錯和函式 f x a 0 a1 a2 1 n 1a n 1 例如 f 3214567 3 2 1 4 5 6 7 4 給定 l,r,k,求在 l,r 區間中,所有 f x k 的 x 的和,即 i lr f i k...
HihoCoder1076 與鏈(數字DP)
時間限制 24000ms 單點時限 3000ms 記憶體限制 256mb 給定 n 和 k。計算有多少長度為 k 的陣列 a1,a2,ak,0 ai 滿足 a1 a2 ak n。對於任意的 i 0,k 1 有 ai and ai 1 ai 1。其中and是與操作。第一行包含乙個整數 t 測試資料組數...