1648-銷售價(jià)值減少的顏色球-排序+求和

寫在前面

這道周賽題卡了我一個(gè)小時(shí),不管怎么改都是最多過47個(gè)用例淘钟,我還以為是越界舱卡,結(jié)果是之前模運(yùn)算沒學(xué)好辅肾,真是難受。轮锥。矫钓。

題目

核心思路

別看這題說的很長(zhǎng),結(jié)合圖示和文字說明舍杜,可以很容易抽象出來:在所給的 inventory 數(shù)組中每次選取一個(gè)最大值inventory[i]新娜,選取的代價(jià)為inventory[i],按此方法選出 orders 個(gè)數(shù)求和即可既绩。
既然每次都選取最大值概龄,那么很直觀可以想到用一個(gè)大頂堆存儲(chǔ)所有數(shù)據(jù),然后每次操作在答案中加最大值饲握,然后將堆頂?shù)淖畲笾禍p一私杜,直至取orders次即可蚕键。不過題目給出的orders的最大值可以到 10 ^ 9,采用堆肯定會(huì)超時(shí)了衰粹。
那么有什么優(yōu)化策略呢锣光?因?yàn)轭}目給的總共要取的數(shù)量orders很大,不妨考慮一下是否可以合并操作從而達(dá)到優(yōu)化時(shí)間復(fù)雜度的效果寄猩。既然題目要從最大數(shù)開始取,我們不妨直接給數(shù)組從大到小排序骑疆,參考下邊圖示田篇。


可以看到,排序后的數(shù)組會(huì)從第一個(gè)元素開始依次減小箍铭,一直減小到圖中的 2泊柬、1,那么如果我們事先知道最終能減小的數(shù)是多少诈火,然后再遍歷一遍數(shù)組使用高斯求和公式即可算出答案兽赁。
由于最后的數(shù)可能不在數(shù)組中,會(huì)不好找冷守,而操作20次得到數(shù)組全為2刀崖,這個(gè)2是很容易得到的,所以不妨直接設(shè)finishNum 表示存在于數(shù)組中的拍摇,滿足使數(shù)組中最大值變?yōu)?code>finishNum的總?cè)?shù)次數(shù)小于等于 orders 的最后一個(gè)數(shù)亮钦,這樣的話我們一次遍歷就可以得到最后這個(gè)數(shù)

int cnt = 0;
int finishNum = nums[0];
int n = nums.length;
int i = 0;

for (i = 1; i < n; i++) {
    int tmp = (nums[i - 1] - nums[i]) * i;
    if (cnt + tmp <= orders) {
        cnt += tmp;
    } else {
        break;
    }
    finishNum = nums[i];
}

這樣得到最后這個(gè)數(shù)finishNum后,就可以分兩部分計(jì)算:

  • 對(duì)于一直到下標(biāo) i 之前所有元素充活,使用高斯求和計(jì)算減小到finishNum所得的價(jià)值
finishNum++;//方便計(jì)算蜂莉,這一步在下邊那種情況之后
for (int j = 0; j < i - 1; j++) {
    res = (res + (((long) nums[j] + finishNum) * ((long) nums[j] - finishNum + 1)) / 2) % MOD;
}
  • 對(duì)于cnt < orders,要在前i個(gè)數(shù)中依次來取混卵,直到cnt == orders為止
    這一部分我們可以看成一個(gè)整體映穗,那么對(duì)于剩余的操作次數(shù)orders - cnt,可以使得這前i個(gè)數(shù)減少(orders - cnt) / i幕随;然后蚁滋,再操作剩下的(orders - cnt) % i次,將其中的(orders - cnt) % i個(gè)數(shù)減一即可赘淮,所以可以分成余數(shù)分別計(jì)算枢赔,而且都是相同的數(shù),可以簡(jiǎn)化計(jì)算
int tmp = finishNum;
long times = (orders - cnt) / i;//商拥知,前i個(gè)數(shù)均要減少times
res = (res + ((tmp - times + tmp + 1) * i * (times) / 2)) % MOD;
cnt += times * i;
//余數(shù)為orders - cnt踏拜,表示還需要在前i個(gè)數(shù)中取orders - cnt 個(gè)數(shù)分別減一
res = (res + (((orders - cnt) % MOD) * ((tmp - times) % MOD)) % MOD) % MOD;

將這兩部分的值全都加在一起取模就可以得到最后的答案了。不過要注意計(jì)算求和公式的書寫低剔,由于模運(yùn)算對(duì)除法不支持運(yùn)算速梗,所以涉及/2的部分只能在最后取模肮塞,否則答案會(huì)不正確。

完整代碼

class Solution {
    private static final int MOD = (int) (1e9 + 7);

    public int maxProfit(int[] nums, int orders) {
        Arrays.sort(nums);
        reverse(nums);

        long res = 0;
        int cnt = 0;
        int finishNum = nums[0];
        int n = nums.length;
        int i = 0;

        for (i = 1; i < n; i++) {
            int tmp = (nums[i - 1] - nums[i]) * i;
            if (cnt + tmp <= orders) {
                cnt += tmp;
            } else {
                break;
            }
            finishNum = nums[i];
        }

        int tmp = finishNum;
        long times = (orders - cnt) / i;//商姻锁,前i個(gè)數(shù)均要減少times
        res = (res + ((tmp - times + tmp + 1) * i * (times) / 2)) % MOD;
        cnt += times * i;
        //余數(shù)為orders - cnt枕赵,表示還需要在前i個(gè)數(shù)中取orders - cnt 個(gè)數(shù)分別減一
        res = (res + (((orders - cnt) % MOD) * ((tmp - times) % MOD)) % MOD) % MOD;

        finishNum++;
        for (int j = 0; j < i - 1; j++) {
            res = (res + (((long) nums[j] + finishNum) * ((long) nums[j] - finishNum + 1)) / 2) % MOD;
        }
        return (int) res;
    }

    public void reverse(int[] nums) {
        if (nums == null)
            return;
        int i = 0, j = nums.length - 1;
        while (i < j) {
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
            i++;
            j--;
        }
    }
}

雖然沒有使用大佬的二分+貪心,不過只有排序總的時(shí)間復(fù)雜度也是O(NlogN)位隶,是符合題目的要求的拷窜,就是數(shù)學(xué)計(jì)算多了一點(diǎn)。
如果文章有寫的不正確的地方還請(qǐng)指出涧黄,感恩相遇~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末篮昧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子笋妥,更是在濱河造成了極大的恐慌懊昨,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件春宣,死亡現(xiàn)場(chǎng)離奇詭異酵颁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)月帝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門躏惋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嚷辅,你說我怎么就攤上這事其掂。” “怎么了潦蝇?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵款熬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我攘乒,道長(zhǎng)贤牛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任则酝,我火速辦了婚禮殉簸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沽讹。我一直安慰自己般卑,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布爽雄。 她就那樣靜靜地躺著蝠检,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挚瘟。 梳的紋絲不亂的頭發(fā)上叹谁,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天饲梭,我揣著相機(jī)與錄音,去河邊找鬼焰檩。 笑死憔涉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的析苫。 我是一名探鬼主播兜叨,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼衩侥!你這毒婦竟也來了国旷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤顿乒,失蹤者是張志新(化名)和其女友劉穎议街,沒想到半個(gè)月后泽谨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體璧榄,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年吧雹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骨杂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雄卷,死狀恐怖搓蚪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丁鹉,我是刑警寧澤妒潭,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站揣钦,受9級(jí)特大地震影響雳灾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜冯凹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一谎亩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宇姚,春花似錦匈庭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至魔熏,卻和暖如春紊选,著一層夾襖步出監(jiān)牢的瞬間啼止,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工兵罢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留献烦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓卖词,卻偏偏與公主長(zhǎng)得像巩那,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子此蜈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 技術(shù)交流QQ群:1027579432即横,歡迎你的加入! 歡迎關(guān)注我的微信公眾號(hào):CurryCoder的程序人生 1....
    CurryCoder閱讀 1,847評(píng)論 0 2
  • 前言 2. 實(shí)現(xiàn) Singleton 3. 數(shù)組中重復(fù)的數(shù)字 4. 二維數(shù)組中的查找 5. 替換空格 6. 從尾到...
    Observer_____閱讀 2,932評(píng)論 0 1
  • 排序算法總結(jié) 分類編程技術(shù) 排序算法平均時(shí)間復(fù)雜度 冒泡排序O(n2) 選擇排序O(n2) 插入排序O(n2) 希...
    Zhs_Android閱讀 201評(píng)論 0 0
  • 在上一章中,我們介紹了基于單調(diào)隊(duì)列和二進(jìn)制DP的優(yōu)化战授。今天我們來看另外3類页藻,斜率優(yōu)化,四邊形不等式植兰,快速冪優(yōu)化份帐。 ...
    西部小籠包閱讀 2,344評(píng)論 4 6
  • 久違的晴天,家長(zhǎng)會(huì)楣导。 家長(zhǎng)大會(huì)開好到教室時(shí)废境,離放學(xué)已經(jīng)沒多少時(shí)間了。班主任說已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)筒繁。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,523評(píng)論 16 22