1. 程式人生 > >演算法題解之容斥原理

演算法題解之容斥原理

        我們有時候在解題的時候,將問題分成幾個子問題,然後疊加,但是答案中有重複解,也就是這些子問題相互具有重疊的部分,如果不分成子問題那麼無疑會使解題過程變得更加麻煩。這時候容斥原理可以幫助解決這一難題。容斥原理就是先將子集問題的解相加,然後減去重複的解,再加上減的過程中重複減的部分,依次遞推。

1.何謂容斥原理

在計數時,必須注意沒有重複,沒有遺漏。為了使重疊部分不被重複計算,人們研究出一種新的計數方法,這種方法的基本思想是:先不考慮重疊的情況,把包含於某內容中的所有物件的數目先計算出來,然後再把計數時重複計算的數目排斥出去,使得計算的結果既無遺漏又無重複,這種計數的方法稱為容斥原理。

        如果被計數的事物有A、B、C三類,那麼,A類和B類和C類元素個數總和= A類元素個數+ B類元素個數+C類元素個數—既是A類又是B類的元素個數-既是A類又是C類的元素個數-既是B類又是C類的元素個數+既是A類又是B類而且是C類的元素個數。(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)。因為當A+B+C之後,相當於把A和B的公共部分加了兩次,所以需要減去,同理也將B和C的公共部分加了兩次,A和C的公共部分加了兩次,所以需要減去。但是在減的過程中多減了ABC的公共部分,所以需要加上,從而得到最終解。         根據以上推理,將公式推導到一般化,公式如下:
                       

2.例題講解

   2、3、5、7的倍數
                                                                         題目大致意思是求求1-N中有多少個不是2或3或5或7的倍數。我們可以先解其反命題,即有多少個是2或3或5或7的倍數,最後用N相減即可。         根據容斥原理:首先,我們先將問題轉化為四個子命題,即2的倍數、3的倍數、5的倍數和7的倍數四個子命題,各自的結果就是N/2、N/3、N/5、N/7。但是2的倍數和3的倍數這兩個解有重複的部分,那就是減去其兩者相乘得到的數的倍數即可,同理其它任意兩個數同理;然後加上任意三個乘積的倍數;接著減去四個數乘積的倍數即可。最後再用N減去前面求到的結果。
程式碼如下:
import java.util.*;
public class Main {
	public static void main(String[] args)
	{
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int total=(n/2+n/3+n/5+n/7)-(n/6+n/10+n/14+n/15+n/21+n/35)+(n/30+n/42+n/70+n/105)-n/210;
		int ans=n-total;
		System.out.println(ans);
	}

}