日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

A+B Problem 详细解答 (转载)

發(fā)布時(shí)間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 A+B Problem 详细解答 (转载) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

此為詳細(xì)裝13版

轉(zhuǎn)載自:https://vijos.org/discuss/56ff2e7617f3ca063af6a0a3

?

全文如下,未作修改,僅供圍觀,不代表個(gè)人觀點(diǎn):

?

你們?cè)趺炊荚谧鼍W(wǎng)絡(luò)流,不就是一道簡(jiǎn)單的遞推嗎???發(fā)表于2016-04-02 10:29

而且你們假惺惺的用網(wǎng)絡(luò)流,過(guò)程中還是要用加法,我一個(gè)加法都沒用。

#include <cstdio> int m, n, a[32768][32768]; int main() { scanf("%d%d", &m, &n); for (int i = 1; i <= m; ++i) { a[i][0] = i; for (int j = 1; j <= n; ++j) { a[0][j] = j; a[i][j] = ++a[i - 1][j]; --a[i - 1][j]; } } printf("%d\n", a[m][n]); }

根據(jù)加法的性質(zhì),0 為加法單元,滿足 m + 0 = m, 0 + n = n
然后就是裸推了:i + j = i + (j - 1) + 1

但是這樣會(huì)超時(shí),而且在 Vijos 上測(cè)數(shù)組太大了,編譯就錯(cuò)誤了。所以要進(jìn)行優(yōu)化,合并一個(gè)狀態(tài):
設(shè) F(i) = i + n, 則 F(0) = n, F(i) = F(i - 1) + 1

#include <cstdio> int m, n, a[32768]; int main() { scanf("%d%d", &m, &n); a[0] = n; for (int i = 1; i <= m; ++i) { a[i] = ++a[i - 1]; --a[i - 1]; } printf("%d\n", a[m]); }

此時(shí)已經(jīng)可以通過(guò)了,然而,本著精益求精的態(tài)度,進(jìn)一步可以用滾動(dòng)數(shù)組優(yōu)化,變成這樣:

#include <cstdio> int m, n, ans; int main() {scanf("%d%d", &m, &n); ans = n; while (m--) ++ans; printf("%d\n", ans); }

這是遞推做法的最優(yōu)解了。然而,事實(shí)上,還可以用位運(yùn)算做,才是真正的最優(yōu)解。
首先,加法分為兩個(gè)步驟,一個(gè)是數(shù)字加,一個(gè)是進(jìn)位。
因?yàn)閱挝欢M(jìn)制中 1 + 1 = 0, 1 + 0 = 1, 0 + 0 = 0, 0 + 1 = 1
正好符合異或的性質(zhì)。
進(jìn)位的部分則為 a & b。
但是第一位不可能進(jìn)位,所以整體移動(dòng)一位,即 (a & b) << 1.
那么 a + b = (a ^ b) + ((a & b) << 1);
出現(xiàn)了加號(hào)!可是這是可以遞歸的,故程序優(yōu)化如下:

#include <cstdio> int m, n; int add(int a, int b) { if (a == 0) return b; if (b == 0) return a; int s = a ^ b; int t = (a & b) << 1; return add(s, t); } int main() { scanf("%d%d", &m, &n); printf("%d\n", add(m, n)); }

顯然,該程序時(shí)間復(fù)雜度為 ?(log max{a, b})
因?yàn)檫@是一個(gè)尾遞歸,所以我們可以通過(guò)迭代消除它。

#include <cstdio> int m, n; int main() {scanf("%d%d", &m, &n); int u = m & n; int v = m ^ n; while (u) { int s = v; int t = u << 1; u = s & t; v = s ^ t; } printf("%d\n", v); }

即為本題最優(yōu)解。
在 Vijos 上看不出差距,在洛谷上,位運(yùn)算解法 2ms 通過(guò),遞推的最優(yōu)解不僅時(shí)間很長(zhǎng),還超時(shí)了一個(gè)點(diǎn)。

不得不說(shuō),本題很考察思維,一步一步優(yōu)化,到達(dá)最優(yōu)。

轉(zhuǎn)載于:https://www.cnblogs.com/radiumlrb/p/5823263.html

總結(jié)

以上是生活随笔為你收集整理的A+B Problem 详细解答 (转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。