1. 程式人生 > >Hihocoder #1527 : 快速乘法 DP

Hihocoder #1527 : 快速乘法 DP

nbsp body ret 進制 == 0ms std tor main

時間限制:20000ms 單點時限:1000ms 內存限制:256MB

描述

在寫代碼時,我們經常要用到類似 x × a 這樣的語句( a 是常數)。眾所周知,計算機進行乘法運算是非常慢的,所以我們需要用一些加法、減法和左移的組合來實現乘一個常數這個操作。具體來講, 我們要把 x × a 替換成:(x<<a0) op1 (x<<a1) op2 (x<<a2) ... opn (x<<an) 這樣的形式,其中opi 是+或者-。

舉個例子:x × 15 = (x<<4) - (x<<0)。

在本題中,假設左移(包括左移0)和加法、減法所需要的時間都是一個單位的時間,上述的例子所需要的時間是3。

現在給定常數 a 的二進制形式,求實現 x × a 最少需要多少單位的時間。

輸入

一個01串,表示 a 的二進制形式,從左到右分別是從高位到低位。

0 < 01串的長度之和 ≤ 106。

a > 0。

輸出

輸出一個數,表示最小需要多少單位的時間可以實現 x × a

樣例輸入
1111
樣例輸出
3
題解:   令f[i][j]表示考慮高於i位,過剩 j*2^i    轉移考慮i-1位 加還是減就好了   時間復雜度O(n)
;
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0
); const int N = 1e6+10, M = 1e3+20,inf = 1e9,mod = 1e9+7; char a[N]; int dp[N][2],n; int main() { scanf("%s",a+1); n = strlen(a+1); a[n+1] = 0; dp[0][0] = -1,dp[0][1] = 1; for(int i = 1; i <= n+1; ++i) dp[i][0] = inf, dp[i][1] = inf; for(int i = 0; i <= n; ++i) { if(a[i+1] == 1) { dp[i+1][0] = min(dp[i+1][0],dp[i][0]+2); dp[i+1][1] = min(dp[i+1][1],dp[i][1]); dp[i+1][0] = min(dp[i+1][0],dp[i][1]+2); } else { dp[i+1][0] = min(dp[i+1][0],dp[i][1]+2); dp[i+1][0] = min(dp[i+1][0],dp[i][0]); dp[i+1][1] = min(dp[i+1][1],dp[i][0]+2); dp[i+1][1] = min(dp[i+1][1],dp[i][1]+2); } } printf("%d\n",max(0,(dp[n+1][0]))); return 0; }

Hihocoder #1527 : 快速乘法 DP