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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

poj3252

發布時間:2024/9/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj3252 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一道組合數學題,連跪一天。。

沒有discuss根本做不出來,但是想想不是很難。

首先,

RoundNumber[start, end] = RoundNumber[0,start] - RoundNumber[0,end - 1] = RoundNumber[0, start + 1] - RoundNumber[0, end]

這是容易證明的。因為一個數字是否是所謂“RoundNumber”,只跟它自己有關,也就是說轉化成二進制的0的個數是否大于1的個數有關。那么他們(獨立的數字,如1,2,3,4)之間是相互獨立的。至于為何要加一或者減一,因為是要包含區間邊界,無論是否小于等于它都會包含(省事兒),所以最后處理一下。

《組合數學》第二章“排列與組合”中,闡述了幾個原理:加法原理、減法原理、乘法原理。各自的前提是不同的,需要仔細去了解。

重點不在上面,上面只是基礎。

首先在高中我們學過組合數的定義:


然后它具有以下常用性質:

1.

2.

3.

4.

性質3常用于打表,因為其具遞推的性質。


切入正題,假設有如下二進制數:


問其是否是RoundNumber?答案是肯定的。

最一開始我們知道,要想求RN[start,end],我們只需要求RN[0,start+1]-RN[0,end]。歸根結底是求RN[0,x]。

把這個八位二進制數分情況討論一下,比它小的分兩種情況,一是1至7位數,二是八位數。

情況一:

一個二進制,長度為Len的數,若使0的個數大于1的個數,可以這么安排:

若Len是奇數,即Len=2*k+1,最高位是1,其余2k位,則有:


至此,Len是奇數時我們解決了。可以直接算這些組合數(從表中直接取,以下代碼就是這么操作的),也可以利用一下上面提供的性質。由性質2知,在性質1和式函數中,最頭的兩個是對稱相等的。那么,上式恰好等于:


若Len是偶數,Len=2*k,最高位是1,其余2k-1位,同理可得:


情況二:當位數為8時:

先放大一下這個二進制數:


可以清晰地看到,第四位,我標記了1。如果將1改為0,那么剩下的四位任意填數都滿足該數(新的)小于這個二進制數(10011000)B。但是不能任意填,還是要滿足0的個數大于1的個數,那么我們有如下結論:

令l為長度,i為當前改變的“1”的位置,如圖中的位置4,zero為0的計數(絕對計數、不包含被改變的第四位數1),a為需要填數的位置(下圖中的虛線框)中1的個數,b為需要填數的位置中0的個數。


有如下等式:


有如下不等式:


解得:


這個式子說明了,至少要填那么b個零,也就是l/2-(zero+1)。注意奇偶。至多呢?至多全填滿唄。填多少?i-1個(空格數)唄。注意,程序中是從高位到地位搜索,i的位置表示的是綠色的1的位置,i-1是空格(虛線框)的個數。

至此,問題解決了,那么代碼就很簡單了。

?

#include<iostream>using namespace std;int c[33][33] = { 0 }; int bin[35]; //十進制n的二進制數void combinations() {for (int i = 0; i <= 32; i++){for (int j = 0; j <= i; j++){if (!j || i == j){c[i][j] = 1;}else{c[i][j] = c[i - 1][j - 1] + c[i - 1][j];}}}return; }void dec_to_bin(int n) {bin[0] = 0;while (n){bin[++bin[0]] = n % 2;n /= 2;}return; }int round(int n) {int i, j;int sum = 0;dec_to_bin(n);/*計算長度小于bin[0]的所有二進制數中RN的個數*/for (i = 1; i < bin[0] - 1; i++){for (j = i / 2 + 1; j <= i; j++){sum += c[i][j];}}/*計算長度等于bin[0]的所有二進制數中RN的個數*/int zero = 0; //從高位向低位搜索過程中出現0的位的個數for (i = bin[0] - 1; i >= 1; i--){if (bin[i]){for (j = (bin[0] + 1) / 2 - (zero + 1); j <= i - 1; j++){sum += c[i - 1][j];}}else zero++;}return sum; }int main() {combinations();int a, b;while (cin >> a >> b){cout << round(b + 1) - round(a) << endl;} }


組合數學,一跪一天,爽!

?

?

轉載于:https://www.cnblogs.com/jiangu66/p/3243989.html

總結

以上是生活随笔為你收集整理的poj3252的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。