ZR1012 Zbox loves keyboard (dp)

10266 단어 동적 기획

Description


텍스트 상자에 x x 개의 문자가 있습니다.2초마다 전체 선택, 복사, 붙여넣기를 할 수 있습니다.1초마다 입력, 체크아웃을 할 수 있습니다.텍스트 상자에 n n n 문자를 입력하려면 몇 초를 구합니까?
1 ≤ n , x ≤ 1 0 6 1\leq n, x\leq 10^6 1≤n,x≤106

Solution


만약 체크아웃 항목이 없다면, 매우 물의 dp문제이다.여기서 모두 선택하고 붙여넣는 작업은 필요하지 않습니다.
체크아웃을 넣으면 체크아웃이 두 개밖에 없는 것을 발견하고 모두 하나를 삭제하거나 삭제한다.모두 삭제하는 것은 한 번만 쓰고, 게다가 처음에 쓴다.하나를 삭제하는 것은 적고, 게다가 시작이나 끝에만 쓴다.현재 S S S인 경우 대상은 T T T T입니다.SS S에서 주기의 전체 복사와 붙여넣기를 시작합니다.약 l o g 2(S -3 T) 필요× 4 log_2(S-T)\times 4 log2​(S−T)×네 번.보수 예측으로는 체크아웃 버튼이 100100번을 넘으면 100번이 더 좋지 않다는 것을 알 수 있기 때문에 체크아웃에 대해서는 100100100 이내의 이동만 하면 된다.국경에 대해서도 비슷한 고려를 하고 있다.
명령 fi fifi는 ii 문자로 최소한 몇 초가 지나면 입력 문자, 백 이내 체크아웃, 전체 복사 후 세 가지 이동을 붙여넣습니다.

Code

#include 
using namespace std;
typedef long long ll;
const int N = 2e6 + 5;
int read() {
	int x = 0, f = 0; char ch = 0;
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
int f[N]; 
int main(){
	memset(f, 0x7f, sizeof(f));
	int x = read(), n = read();
	f[x] = 0, f[0] = min(3, x);
	int m = max(x, n) + 100;
	for (int i = 1; i <= m; i++) {
		f[i] = min(f[i], f[i - 1] + 1);
		for (int j = 1; j <= 100; j++) f[i] = min(f[i], f[i + j] + j);
		for (int j = 2; i * j <= m; j++) f[i * j] = min(f[i * j], f[i] + 4 + (j - 1) * 2);
	} 
	printf("%d
"
, f[n]); return 0; }

좋은 웹페이지 즐겨찾기