noip模擬賽 王強的疑惑 題解

2022-05-05 21:15:11 字數 2113 閱讀 7464

考試題。

是個dp。

50分可以通過子集列舉+線段覆蓋(貪心)完成。

考試沒時間寫了乙個子集列舉30分。

#include #include #include #include using namespace std;

const int maxn = 20;

int read()

while (isdigit(ch)) return u * f;

}//int dp[maxn][maxn]...

struct ioib[maxn];

bool cmp(ioi a, ioi b)

int a[maxn], n, q, seq[maxn], last;

double now = 0, ans;

void print_subset(int s, int n)

int main()

sort(b+1, b+1+n, cmp);

for(int i = 1; i < (1 << n); i++)

}if(now > ans)

}printf("%0.3lf\n",ans);

for(int i = 1; i <= n; i++)

return 0;

}

注意一點:memset初始化是o(n)的。儘管上次morslin跟我說做試驗memset確實比for一遍快...所以我信了他每次列舉memset了乙個1e6的陣列..tle

考慮正解的dp。

說過狀態設的好,轉移就方便。

一開始設的dp[i][j]表示前i個選了j個的最優..

轉移個錘子。

正解:不妨設dp[i]表示在第i時,可以獲得的最大期望(此期望非彼期望)。

於是只有在第j個結束時間為i才轉移,其他的是dp[i] = dp[i-1]

注意a[j].l這個邊界,要》q才能轉移,會被卡。不寫只有50分。

$ if(a[j].r == i && a[j].l >= q) $

$ dp[i] = max(dp[i], dp[a[j].l-q] + a[j].p) $

這時候得到乙個o(mn)的dp。m為最大時間

考慮再優化,如果我們先給每個資訊排一遍序,這樣我們隨著時間i的增大,每個a[j].l和a[j].r也在增大。記錄上次列舉到的j是多少,記為pos,下次直接從j = pos開始。

我們再去列舉每個j的時候就不需要從1開始了,因為每次滿足的先行條件是a[j].r == i。

注意一點,不論這次a[j]有沒有更新dp[i]的值,我們的pos都要改變,否則還是tle。

code:

#include #include #include #include #include using namespace std;

const int maxn = 1e6 + 10;

inline int read()

while (isdigit(ch)) return u * f;

}double dp[maxn];

struct ioia[maxn];

int n, m, q, pos = 1, pre[maxn], ans[maxn], ans[maxn], cnt;

bool cmp(ioi a, ioi b)

int main()

sort(a+1, a+1+n, cmp);

for(int i = 1; i <= m; i++)

if(a[j].num == 1 && dp[i] < dp[a[j].l-q] + a[j].p)

pos = j;

}} }

int now = m;

while(now)

printf("%0.3lf\n",dp[m]);

for(int i = cnt; i >= 1; i--)

printf("%d ",ans[i]);

return 0;

}

輸出路徑的時候是while(now),不是while(pre[now])..

我說怎麼輸出不了最後乙個..

校內模擬 王強的疑惑

時限 2s 空間 256mb 在遙遠的 mathcal 星系中,生活著一種神奇的生物 王 強,他們鱔長於 ak oi 比賽,在乙個 mathcal 物復甦的季節,乙隻年輕的雄性王強開始了他的 ak 活動.mathcal 星系中有 n 個星球在舉行 oi 比賽,星球的名稱分別是 1 號星球,2 號星球...

NOIP 模擬試題之小凱的疑惑題解

提取碼 31p6 描述小凱手中有兩種面值的金幣,兩種面值均為正整數且彼此互素。每種金幣小凱都有 無數個。在不找零的情況下,僅憑這兩種金幣,有些物品他是 無法準確支付的。現在小凱想知道在無法準確支付的物品中,最貴的價值是多少金幣?注意 輸入資料保證存在小凱無法準確支付的商品。輸入輸入資料僅一行,包含兩...

NOIP模擬賽2019 8 30題解

維護乙個棧 從前往後掃瞄,如果棧為空或當前數及之後數中的最大值大於棧頂的數,就將最大值之前的所有數入棧,並且把最大值儲存在答案中。否則將棧頂的元素彈出,並儲存在答案中。由於最大值從後往前是單調遞增的,所以直接用乙個陣列維護就可以o 1 查詢 include.h using namespace std...