時間限制:20000ms
單點時限:1000ms
記憶體限制:256mb
描述在寫**時,我們經常要用到類似 x × a 這樣的語句( a 是常數)。眾所周知,計算機進行乘法運算是非常慢的,所以我們需要用一些加法、減法和左移的組合來實現乘乙個常數這個操作。具體來講, 我們要把 x × a 替換成:(x
<0) op1 (x
<1) op2 (x
<2) ... opn (x
舉個例子:x × 15 = (x <<4) - (x <<0)。 在本題中,假設左移(包括左移0)和加法、減法所需要的時間都是乙個單位的時間,上述的例子所需要的時間是3。 現在給定常數 a 的二進位制形式,求實現 x × a 最少需要多少單位的時間。 輸入乙個01串,表示 a 的二進位制形式,從左到右分別是從高位到低位。 0 < 01串的長度之和 ≤ 106。 a > 0。 輸出輸出乙個數,表示最小需要多少單位的時間可以實現 x × a。 樣例輸入 1111 樣例輸出 3錯解: 貪心選擇超過兩個連續的1的決策不如使用高位減低位的方法,110不如1<<3 – 1<<1 然後,單個1選擇直接加上。 如果兩個大塊(2個連續1以上)中間之隔為1個0,那麼可以合併,110110不如 1<<6 – 1<<4 + 1<<3 – 1<<1 = 1<<6 – 1 <<3 – 1<<1 是我太弱,所以沒有貪出來,少考慮了一種情況就是對於類似1101011這樣,可以抉擇把0填滿然後變成全1,用1<<7-1<<0. 錯誤**:#include #include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef pair
p;typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const
double pi = acos(-1.0
);const
double eps = 1e-9
;const
int n = 1e6 + 5
;char
s[n];
intmain()
if(k == 1) cnt++;
else
if(k >= 2) cnt += 2
;
if(k >= 2 && i+2
< n && s[i+1] == '
1' && s[i+2] == '1'
) cnt -= 1
;
if(i < n && s[i] == '0'
) i++;
}printf(
"%d\n
", 2*cnt-1
); }
return0;
}
ac貪心:
#include #include#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef pair
p;typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const
double pi = acos(-1.0
);const
double eps = 1e-9
;const
int n = 1e6 + 5
;char
s[n];
intmain()
if(k == 1) cnt++;
else
if(k >= 2) cnt += 2
;
if(k >= 2 && i+1
< n && s[i+1] == '1'
)
if(i < n && s[i] == '0'
) i++;
}printf(
"%d\n
", 2*cnt-1
); }
return0;
}
題解:很多都是二冪劃分的解釋,也可以用dp來做
從低位往高位考慮。dp[i]表示第i位的時候需要進行最少運算元
如果當前位是0,dp[i] = dp[i-1]
如果當前位是1,可以有兩種選擇,直接加上dp[i] = dp[i-1] + 1;
或者,把某一部分的0全部補上,然後用高位1減去,例如01100 = 10000 – 00100,也就是 [x, i]全部都變成1,也就是要補上x~i的0
dp[i] =min
#include #include#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef pair
p;typedef
long
long
ll;const
int inf = 0x3f3f3f3f
;const
double pi = acos(-1.0
);const
double eps = 1e-9
;const
int n = 1e6 + 5
;char
s[n];
intsum[n], dp[n];
intmain()
if(mx == -1 || dp[i-1] + 2 + sum[i+1] - sum[i-1] <= dp[mx-1] + 2 + sum[i+1] - sum[mx-1
]) mx =i;
}printf(
"%d\n
", 2*dp[n]-1
);
return0;
}
亂搞 hihocoder1527 快速乘法
在寫 時,我們經常要用到類似 x a 這樣的語句 a 是常數 眾所周知,計算機進行乘法運算是非常慢的,所以我們需要用一些加法 減法和左移的組合來實現乘乙個常數這個操作。具體來講,我們要把 x a替換成 x op1 x op2 x opn x 這樣的形式,其中op i 是 或者 舉個例子 x 15 x...
Prince and Princess 動態規劃
題目大意 求兩個序列的最長子序列 include include include includeusing namespace std int n,p,q const int maxn 250 250 int num1 maxn int hash maxn stack maxn int main i...
Colored Rectangles 動態規劃
題意 三種木棍,分別有 r對 g對 b對兩種不同木棍對可以弄移乙個矩形,要求矩形面積總和最大 思路 看題面,這種幾個變數互相影響並且最終目標固定的題目感覺就要用dp,而且資料比較小應該就是能用三維dp,雖然我比賽時沒做出來,但是我想的挺明白的,狀態轉移就是dp i j k max dp i 1 j ...