国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

2022CCSP T1最少充電次數(shù)

這篇具有很好參考價值的文章主要介紹了2022CCSP T1最少充電次數(shù)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

記錄第一次CCSP競賽。一共3題,只做出第一題,用時3h30m(累),ac了開心地吃了個午飯。然而飯飽之后,大腦完全提不起神看著題面昏昏欲睡。第二題是虛擬內(nèi)存,超級大模擬,剛好這個學(xué)期學(xué)os,但是翹了太多課完全看不懂,自己看ppt學(xué)了一點多級頁表,但是1v0,1v1啥的想不明白怎么對應(yīng)呀。第三題跟數(shù)據(jù)庫系統(tǒng)有關(guān),高性能 RDF 圖查詢系統(tǒng),給了一個代碼框架,稍微看了看,代碼十分規(guī)范,應(yīng)用了很多C++繼承、虛基類等等特性,然后按要求實現(xiàn)一些函數(shù)方法,不會。下面主要記錄第一題的思路。


T1 最少充電次數(shù)

題面

2022CCSP T1最少充電次數(shù),CSP 認(rèn)證,算法,動態(tài)規(guī)劃,c++,CCSP競賽
數(shù)據(jù)范圍
2022CCSP T1最少充電次數(shù),CSP 認(rèn)證,算法,動態(tài)規(guī)劃,c++,CCSP競賽

思路

DP,有電量、充電時間兩個維度約束,一開始我定義的狀態(tài)是 d p [ n ] [ r t i m e ] [ r b a t ] dp[n][rtime][rbat] dp[n][rtime][rbat],維度的含義是當(dāng)前站點、剩余充電時間和剩余電量,存儲相應(yīng)的最小充電次數(shù),但是更新該狀態(tài)數(shù)組會發(fā)現(xiàn)剩余電量這一維度是 ( 1 < < 30 ) ≈ 1 e 9 (1<<30)\approx1e9 (1<<30)1e9,這肯定T飛。

其實看到問題很容易產(chǎn)生貪心想法,選擇充電效率較高的充電站以在相同的時間內(nèi)獲得更多電量。那其他維度相同的狀態(tài)中是不是應(yīng)選擇剩余電量更多的狀態(tài)?想到這點,重新定義狀態(tài) d p [ n ] [ r t i m e ] [ a n s ] dp[n][rtime][ans] dp[n][rtime][ans],調(diào)換一下,最后一維表示充電次數(shù),數(shù)組存儲最大剩余電量。
遞推分為行駛和充電,由于當(dāng)前狀態(tài)僅僅和前面一個狀態(tài)有關(guān),將第一維度賦為2,滾動數(shù)組以壓縮空間。
① 行駛至下一個充電站:

dp[s ^ 1][j][k] = max(dp[s ^ 1][j][k], dp[s][j][k] - d[i + 1] + d[i]);

② 充電:

dp[s ^ 1][j][k] = dp[s][j][k];	// t==0
dp[s ^ 1][j - t][k + 1] = max(dp[s ^ 1][j - t][k + 1], dp[s][j][k] + t * cspeed[i]);	// t!=0

優(yōu)化

仔細(xì)算一下復(fù)雜度,充電站數(shù)×總最大充電時間×充電次數(shù), 512 × 1 e 4 × 512 ≈ 2.5 e 9 512\times1e4\times512\approx2.5e9 512×1e4×5122.5e9,提交上去只能過前面兩個點。
然后,開始想辦法借助STL進(jìn)行優(yōu)化(感覺CCF比賽我總是靠亂搞STL出奇跡)。
用數(shù)組存儲狀態(tài),你只能按下標(biāo)進(jìn)行遞推,但這會冗余考慮很多不可能的狀態(tài),從不可能的狀態(tài)遞推怎么也無法到達(dá)可能的狀態(tài)。于是乎我改用 m a p < n o d e , i n t > s t a t [ 2 ] map<node, int> stat[2] map<node,int>stat[2],其中 node 的定義為

struct node {
    int rtime, cnt;
    bool operator < (const node &d) const {
        return cnt < d.cnt;
    }
};

這個結(jié)構(gòu)僅僅存儲有效狀態(tài),因而我們也只會從有效狀態(tài)開始遞推,避免冗余。

AC代碼

2022CCSP T1最少充電次數(shù),CSP 認(rèn)證,算法,動態(tài)規(guī)劃,c++,CCSP競賽
太菜了,一發(fā)AC高興得不得來了。。。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

int d[550], tlimit[550], cspeed[550];

struct node {
    int rtime, cnt;
    bool operator < (const node &d) const {
        return cnt < d.cnt;
    }
};
// 只對有效狀態(tài)進(jìn)行轉(zhuǎn)移
map<node, int> stat[2];

void solve() {
    int totdis, n, maxtime, initbat;
    cin >> totdis >> n >> maxtime >> initbat;
    d[0] = 0;
    for (int i = 1; i <= n; i++) cin >> d[i];
    for (int i = 0; i < n; i++) cin >> tlimit[i];
    for (int i = 0; i < n; i++) cin >> cspeed[i];

    stat[1][{maxtime, 0}] = initbat;

    int s = 1;
    for (int i = 0; i < n; i++) {
        // 從i-1行駛至i
        for (const auto &[x, r] : stat[s]) {
            if (stat[s][x] - d[i + 1] + d[i] >= 0) {
                stat[s ^ 1][x] = stat[s][x] - d[i + 1] + d[i];
            }
        }

        stat[s].clear();
        s ^= 1;

        // 充電
        for (int t = 0; t <= tlimit[i]; t++) {
            // 狀態(tài)轉(zhuǎn)移
            for (const auto &[x, r] : stat[s]) {
                if (x.rtime < t) continue;
                if (t) {
                    int tmp = 0;
                    if (stat[s ^ 1][{x.rtime - t, x.cnt + 1}]) {
                        tmp = stat[s ^ 1][{x.rtime - t, x.cnt + 1}];
                    }
                    stat[s ^ 1][{x.rtime - t, x.cnt + 1}] = max(tmp, r + t * cspeed[i]);
                }
                else { stat[s ^ 1][{x.rtime, x.cnt}] = r; }
            }
        }

        stat[s].clear();
        s ^= 1;
    }

    // ans
    for (const auto &[x, r] : stat[s]) {
        if (r >= totdis - d[n]) {
            cout << x.cnt << '\n';
            return;
        }
    }
    { cout << "-1\n"; }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}

提交代碼

僅僅作為個人記錄。文章來源地址http://www.zghlxwxcb.cn/news/detail-717552.html

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
//#define Debug
//#define arr
// 選擇充電不一定會充至?xí)r間上限
// dp[n][rtime][rbat]:充電次數(shù),(當(dāng)前所在充電站、剩余充電時間、剩余電量)
// 512*(1e4)*(1<<30)
// 到達(dá)終點最少充電次數(shù)
/*
 * dp[i][rtime][rbat]=dp[i-1][rtime][rbat+d[i]-d[i-1]]
 * dp[i][rtime-t][rbat+t*cspeed[i]]=dp[i][rtime][rbat]+1,t<=tlimit[i]
 */

// 分組背包
// 每組取物品個數(shù)=每個服務(wù)站充電時間
// 充電速度不同->選擇剩余電量最多的狀態(tài)
// dp[n][rtime][ans]

/*
 * dp[n][rtime][i]=max(dp[n][rtime+t][i-1]+t*cspeed[i])
 */

int d[550], tlimit[550], cspeed[550];
#ifdef arr
int dp[2][10010][550];   // 該狀態(tài)下最大剩余電量
#else
struct node {
    int rtime, cnt;
    bool operator < (const node &d) const {
        return cnt < d.cnt;
    }
};
// 只對有效狀態(tài)進(jìn)行轉(zhuǎn)移
map<node, int> stat[2];
#endif

void solve() {
    int totdis, n, maxtime, initbat;
    cin >> totdis >> n >> maxtime >> initbat;
    d[0] = 0;
    for (int i = 1; i <= n; i++) cin >> d[i];
    for (int i = 0; i < n; i++) cin >> tlimit[i];
    for (int i = 0; i < n; i++) cin >> cspeed[i];
#ifdef arr
    memset(dp, -1, sizeof dp);
    dp[1][maxtime][0] = initbat;    // 初始化
#else
    stat[1][{maxtime, 0}] = initbat;
#endif

    int s = 1;
    for (int i = 0; i < n; i++) {
        // 從i-1行駛至i
#ifdef arr
        for (int j = maxtime; j >= 0; j--) {
            for (int k = 0; k <= i; k++) {
                dp[s ^ 1][j][k] = max(dp[s ^ 1][j][k], dp[s][j][k] - d[i + 1] + d[i]);
            }
        }
#else
        for (const auto &[x, r] : stat[s]) {
            if (stat[s][x] - d[i + 1] + d[i] >= 0) {
                stat[s ^ 1][x] = stat[s][x] - d[i + 1] + d[i];
            }
        }
#endif

#ifdef Debug
        cout << "arrive: " << i << '\n';
//        for (int j = maxtime; j >= 0; j--) {
//            cout << "rest time: " << j << '\n';
//            for (int k = 0; k <= i && k <= n; k++) {
//                cout << "(" << k << "," << dp[s ^ 1][j][k] << ") ";
//            }
//            cout << '\n';
//        }   cout << '\n';
        for (const auto &x : stat[s ^ 1]) {
            cout << x.rtime << ' ' << x.cnt << ' ' << x.rbat << '\n';
        }   cout << '\n';
#endif
#ifdef arr
        memset(dp[s], -1, sizeof dp[s]);
#else
        stat[s].clear();
#endif
        s ^= 1;
        // 充電
        for (int t = 0; t <= tlimit[i]; t++) {
            // 狀態(tài)轉(zhuǎn)移
#ifdef arr
            for (int j = maxtime; j >= 0; j--) {
                if (j < t) break;
                for (int k = 0; k <= i && k <= n; k++) {
                    if (!t) {
                        dp[s ^ 1][j][k] = dp[s][j][k];
                    }
                    else {
                        if (dp[s][j][k] < 0) continue;
                        dp[s ^ 1][j - t][k + 1] = max(dp[s ^ 1][j - t][k + 1], dp[s][j][k] + t * cspeed[i]);
                    }
                }
            }
#else
            for (const auto &[x, r] : stat[s]) {
                if (x.rtime < t) continue;
                if (t) {
                    int tmp = 0;
                    if (stat[s ^ 1][{x.rtime - t, x.cnt + 1}]) {
                        tmp = stat[s ^ 1][{x.rtime - t, x.cnt + 1}];
                    }
                    stat[s ^ 1][{x.rtime - t, x.cnt + 1}] = max(tmp, r + t * cspeed[i]);
                }
                else { stat[s ^ 1][{x.rtime, x.cnt}] = r; }
            }
#endif
        }


#ifdef Debug
        cout << "charge: " << i << '\n';
//        for (int j = maxtime; j >= 0; j--) {
//            cout << "rest time: " << j << '\n';
//            for (int k = 0; k <= (i + 1) && k <= n; k++) {
//                cout << "(" << k << "," << dp[s ^ 1][j][k] << ") ";
//            }
//            cout << '\n';
//        }   cout << '\n';
        for (const auto &x : stat[s ^ 1]) {
            cout << x.rtime << ' ' << x.cnt << ' ' << x.rbat << '\n';
        }   cout << '\n';
#endif
//        memset(dp[s], -1, sizeof dp[s]);

#ifdef arr
        memset(dp[s], -1, sizeof dp[s]);
#else
        stat[s].clear();
#endif
        s ^= 1;
    }

    // ans
#ifdef arr
    for (int k = 0; k <= n; k++) {
        for (int j = maxtime; j >= 0; j--) {
            if (dp[s][j][k] >= totdis - d[n]) {
                cout << k << '\n';
                return;
            }
        }
    }
#else
    for (const auto &[x, r] : stat[s]) {
        if (r >= totdis - d[n]) {
            cout << x.cnt << '\n';
            return;
        }
    }
#endif
    { cout << "-1\n"; }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();
    return 0;
}

/*
10 2 2 2
3 8
1 1
2 3

10 2 2 5
3 8
1 1
3 2
 */

到了這里,關(guān)于2022CCSP T1最少充電次數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C++二分算法:得到子序列的最少操作次數(shù)

    二分查找算法合集 給你一個數(shù)組 target ,包含若干 互不相同 的整數(shù),以及另一個整數(shù)數(shù)組 arr ,arr 可能 包含重復(fù)元素。 每一次操作中,你可以在 arr 的任意位置插入任一整數(shù)。比方說,如果 arr = [1,4,1,2] ,那么你可以在中間添加 3 得到 [1,4,3,1,2] 。你可以在數(shù)組最開始或最后

    2024年02月05日
    瀏覽(18)
  • 【算法題】2602. 使數(shù)組元素全部相等的最少操作次數(shù)

    給你一個正整數(shù)數(shù)組 nums 。 同時給你一個長度為 m 的整數(shù)數(shù)組 queries 。第 i 個查詢中,你需要將 nums 中所有元素變成 queries[i] 。你可以執(zhí)行以下操作 任意 次: 將數(shù)組里一個元素 增大 或者 減小 1 。 請你返回一個長度為 m 的數(shù)組 answer ,其中 answer[i]是將 nums 中所有元素變成

    2023年04月24日
    瀏覽(13)
  • 【動態(tài)規(guī)劃】【記憶化搜索】【回文】1312讓字符串成為回文串的最少插入次數(shù)

    【動態(tài)規(guī)劃】【記憶化搜索】【回文】1312讓字符串成為回文串的最少插入次數(shù)

    【動態(tài)規(guī)劃】【字符串】【表達(dá)式】2019. 解出數(shù)學(xué)表達(dá)式的學(xué)生分?jǐn)?shù) 動態(tài)規(guī)劃匯總 記憶化搜索 回文 字符串 給你一個字符串 s ,每一次操作你都可以在字符串的任意位置插入任意字符。 請你返回讓 s 成為回文串的 最少操作次數(shù) 。 「回文串」是正讀和反讀都相同的字符串。

    2024年02月19日
    瀏覽(18)
  • CCF CSP認(rèn)證最新2022-12題解c++(全網(wǎng)首發(fā))

    CCF CSP認(rèn)證最新2022-12題解c++(全網(wǎng)首發(fā))

    第一次寫題解,代碼沒帶注釋,請諒解,盡力在題目分析中說明白. http://118.190.20.162/view.page?gpid=T160 問題描述 輸入格式 輸出格式 輸出到標(biāo)準(zhǔn)輸出中。 輸出一個實數(shù),表示該項目在當(dāng)前價值標(biāo)準(zhǔn)下的總盈利或虧損。 題目分析 按照題意將除第一年外的每年x元都轉(zhuǎn)換為當(dāng)前的實際價

    2024年02月13日
    瀏覽(1585)
  • 華為OD機(jī)考算法題:根據(jù)某條件聚類最少交換次數(shù)

    題目部分 解讀與思路 代碼實現(xiàn) 題目 根據(jù)某條件聚類最少交換次數(shù) 難度 難 題目說明 給出數(shù)字K,請輸出所有結(jié)果小于K的整數(shù)組合到一起的最少交換次數(shù)。 組合一起是指滿足條件的數(shù)字相鄰,不要求相鄰后在數(shù)組中的位置。 數(shù)據(jù)范圍 -100 =K = 100 -100 = 數(shù)組中數(shù)值 = 100 輸入描

    2024年02月09日
    瀏覽(18)
  • 第27次CCF-CSP計算機(jī)軟件能力認(rèn)證(2022-09-18)

    第27次CCF-CSP計算機(jī)軟件能力認(rèn)證(2022-09-18)

    個人感想:算是完成了自己期望的目標(biāo)300分吧,比之前進(jìn)步了。第一題花了十五分鐘,有十多分鐘都是在看題。第二題01背包花了半個小時,太久沒看動態(tài)規(guī)劃了模板都忘得差不多。第三題的大模擬依舊有難度,寫完的時候離比賽結(jié)束還剩一個小時。第四題大概看了一下應(yīng)該

    2024年02月09日
    瀏覽(90)
  • 【LeetCode 算法】Minimum Operations to Halve Array Sum 將數(shù)組和減半的最少操作次數(shù)-Greedy

    給你一個正整數(shù)數(shù)組 nums 。每一次操作中,你可以從 nums 中選擇 任意 一個數(shù)并將它 減小 到 恰好 一半 。(注意,在后續(xù)操作中你可以對減半過的數(shù)繼續(xù)執(zhí)行操作) 請你返回將 nums 數(shù)組和 至少 減少一半 的 最少 操作數(shù)。 1 = n u m s . l e n g t h = 1 0 5 1 = n u m s [ i ] = 1 0 7 1 = num

    2024年02月15日
    瀏覽(22)
  • 1210. 穿過迷宮的最少移動次數(shù)

    1210. 穿過迷宮的最少移動次數(shù)

    你還記得那條風(fēng)靡全球的貪吃蛇嗎? 我們在一個? n*n ?的網(wǎng)格上構(gòu)建了新的迷宮地圖,蛇的長度為 2,也就是說它會占去兩個單元格。蛇會從左上角( (0, 0) ?和? (0, 1) )開始移動。我們用? 0 ?表示空單元格,用 1 表示障礙物。蛇需要移動到迷宮的右下角( (n-1, n-2) ?和? (

    2024年02月02日
    瀏覽(19)
  • 將數(shù)組和減半的最少操作次數(shù)(力扣)

    將數(shù)組和減半的最少操作次數(shù)(力扣)

    給你一個正整數(shù)數(shù)組 nums 。每一次操作中,你可以從 nums 中選擇 任意 一個數(shù)并將它減小到 恰好 一半。(注意,在后續(xù)操作中你可以對減半過的數(shù)繼續(xù)執(zhí)行操作) 請你返回將 nums 數(shù)組和 至少 減少一半的 最少 操作數(shù)。 示例 1: 示例 2: 每次操作,會將數(shù)組中的一個數(shù)減半。

    2024年02月16日
    瀏覽(18)
  • 輸入單詞需要的最少按鍵次數(shù) I

    輸入單詞需要的最少按鍵次數(shù) I

    輸入單詞需要的最少按鍵次數(shù) I 1 = word.length = 26 word 僅由小寫英文字母組成 word 中的所有字母互不相同 因為word 中的所有字母互不相同,可以以任意8個字符為一組,第一組每個字符需要按鍵一次,第二組需要按鍵兩次,以此類推…根據(jù)字符串長度將每組字符的按鍵次數(shù)累加起

    2024年01月24日
    瀏覽(12)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包