LintCode-4 Keys Keyboard 數學解法

867. 4 Keys Keyboard

Imagine you have a special keyboard with the following keys:

Key 1: (A): Print one ‘A’ on screen.

Key 2: (Ctrl-A): Select the whole screen.

Key 3: (Ctrl-C): Copy selection to buffer.

Key 4: (Ctrl-V): Print buffer on screen appending it after what has already been printed.

Now, you can only press the keyboard for N times (with the above four keys), find out the maximum numbers of ‘A’ you can print on screen.

注意事項
  1. 1 <= N <= 50
  2. Answers will be in the range of 32-bit signed integer.

樣例

Given N = 3, return 3.

Explanation: 
We can at most get 3 A's on screen by pressing following key sequence:
A, A, A

Given N = 7, return 9.

Explanation: 
We can at most get 9 A's on screen by pressing following key sequence:
A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V

做的時候感覺應該有什麼規律,沒用dp做,憋了半天總算找出來了
結論是將N+1分解成整數個5和整數個4,不能滿足的情況(N<=6,N=10)單列出來,有多少個4就乘多少個3,有多少個5就乘多少個4,兩者乘積就是答案。

分析:
首先,N<=6時最大字符數即爲N,A的輸入次數<=5,且只會在一開始輸入,一旦開始CV操作便不會再輸入。
Ctrl+A,Ctrl+C,Ctrl+V一套下來會使之前的字符數*2,如果再加一個Ctrl+V就是*3(4次操作),再加一個是*4(5次操作),最多到*5(6次操作)。
因爲五次Ctrl+V(7次操作)即n*6等同於n*2*3,沒有意義。
因此,例如N=12可以拆分爲4(輸入3次A,3次操作)*3(CtrlA,CtrlC,CtrlV,CtrlV,4次操作)*3(同上,4次操作)
可以發現,複製時的操作次數-1=複製次數,而輸入的操作次數=字符數;
但輸入只進行一次,因此可以在一開始就將N+1,方便後面的計算。

另一方面,n*5在大部分情況下可以轉化:
n*3*5(n*15)=n*4*4(n*16);(4+6=5+5操作次數),後者字符數更多
n*4*4*5(n*80)=n*3*3*3*3(n*81);(5+5+6=4+4+4+4),後者字符數更多
n*3*4*5=n*4*4*4,同第一種情況
……
可以看出,*5操作唯有在N=5和N=10(N+1==11,操作次數11=5+6=>4*5)時不能轉化,必須使用,做一個判斷即可。
綜上,算法需要求儘可能多的*4,而前提是需要有足夠更多的*3操作來保證操作次數正好用完,因此需要求一個整數線性規劃:

min x/max y
S.T.
4x+5y=N(x爲*3次數,y爲*4次數)
x,y∈Z+
class Solution {
public:
    /**
     * @param N: an integer
     * @return: return an integer
     */
    int maxA(int N) {
        // write your code here
        if(N<=6) return N;
        N++;
        if(N-1==10) return 20;
        for(int n3=0;n3<=N/4;n3++)
        {
            if((N-n3*4)%5==0) return pow(3,n3)*pow(4,(N-n3*4)/5);
        }
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章