Educational Codeforces Round 91 (Rated for Div. 2) D.Berserk And Fireball(思维,暴力破解,分情况)
題目傳送
題意:
現(xiàn)在有一個(gè)排列,再給出一個(gè)刪除后的數(shù)組,刪除操作只有倆種:一種是,選擇連續(xù)的k個(gè)數(shù),刪除,消耗x點(diǎn)代價(jià)。另一種是,選擇連續(xù)的倆個(gè)數(shù),刪除其中小的數(shù),消耗y點(diǎn)代價(jià)。現(xiàn)在問(wèn),能否得到刪除后的數(shù)組,如果不能輸出-1,如果能,請(qǐng)打出最小代價(jià)。
思路:
很明顯就是分情況操作,先記錄下,每個(gè)數(shù)的位置,然后在刪除后的數(shù)組中對(duì)應(yīng)起來(lái),看刪除的哪些數(shù),枚舉刪除的數(shù)的最大值(這里要注意,因?yàn)閰^(qū)間不會(huì)重復(fù),所以我們暴力枚舉最大值,最壞也就總共2e5次操作),再看刪除的這些數(shù)是否滿(mǎn)足刪除條件。
1.如果y*k大于等于x,那么肯定是代價(jià)最小的(每次選擇連續(xù)的倆個(gè)數(shù)),但是我們要觀察是否滿(mǎn)足刪除條件,條件:左端點(diǎn),或者右端點(diǎn)的值要大于這之間的最值
**(1)**如果滿(mǎn)足這個(gè)條件,那么直接刪用y代價(jià),刪除端點(diǎn)中間的數(shù)即可
(2)如果不滿(mǎn)足,那么我們要看是否大于k,如果大于了k,我們就可以用y的代價(jià)刪除這個(gè)最值,而在這之間,我們可以利用這個(gè)最值去刪除其他數(shù)(不用管這個(gè)過(guò)程,我們只知道留下最值即可),所以代價(jià)消耗是x + (中間要?jiǎng)h除的個(gè)數(shù)-k)*y。
如果都不滿(mǎn)足這個(gè)條件,那么說(shuō)明這個(gè)數(shù)最大值是刪不了的,所以輸出-1
2.如果y*k > x,那么我們就要盡量的用x的代價(jià)去刪除數(shù)。條件;刪除的數(shù)的個(gè)數(shù)大于等于k
(1)如果滿(mǎn)足條件,那么代價(jià)為(個(gè)數(shù)/k)*x + (個(gè)數(shù)%k)*y
(2)如果不滿(mǎn)足條件,那么沒(méi)辦法,我們只能用y的代價(jià)去刪,那么回到1中所述,尋找最值,如果滿(mǎn)足條件就刪,不滿(mǎn)足退出輸出-1
AC代碼
#include <bits/stdc++.h> inline long long read(){char c = getchar();long long x = 0,s = 1; while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();} while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();} return x*s;} using namespace std; #define NewNode (TreeNode *)malloc(sizeof(TreeNode)) #define Mem(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x)&(-x) const int N = 2e5 + 10; const long long INFINF = 0x7f7f7f7f7f7f7f; const int INF = 0x3f3f3f3f; const double EPS = 1e-7; const int mod = 1e9+7; const double II = acos(-1); const double PP = (II*1.0)/(180.00); typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<ll,ll> piil; ll arr[N],ans[N],vis[N]; ll solve(ll l,ll r) {ll Max = 0;for(ll i = l+1;i < r;i++)Max = max(Max,arr[i]);return Max; }//枚舉最大值 signed main() {std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);// freopen("input.txt","r",stdin);// freopen("output.txt","w",stdout);ll n,m,x,k,y,a = 2,sum = 0,flag = 0,flag1 = 0;cin >> n >> m >> x >> k >> y;for(ll i = 1;i <= n;i++) {cin >> arr[i];vis[arr[i]] = i;}//記錄位置for(ll i = 1;i <= m;i++) cin >> ans[i];if(ans[1] != arr[1]) a--,ans[0] = arr[1];//這里如果ans[1] != arr[1],說(shuō)明前面還刪了數(shù),還得加個(gè)端點(diǎn)進(jìn)去if(ans[m] != arr[n]) ans[++m] = arr[n],flag1 = 1;//與上面同理for(ll i = a;i <= m;i++){ll l = vis[ans[i-1]],r = vis[ans[i]];//端點(diǎn)位置ll num = r-l-1;//中間要?jiǎng)h除的個(gè)數(shù)ll Max = solve(l,r);if(i == 1) num++,Max = max(Max,arr[l]);//這里注意,如果在上面我們添加了端點(diǎn)進(jìn)去,那么這個(gè)端點(diǎn)其實(shí)也是要?jiǎng)h的,所以需要更新信息if(i == m && flag1) num++,Max = max(Max,arr[r]);//與上同理if(num < 0) {flag = 1;break;}//如果位序發(fā)生了改變,那么不可能if(y*k <= x && (Max < arr[l] || Max < arr[r]))//分情況sum += y*num;else if(y*k <= x && num >= k)sum += (x + (num-k)*y);else if(y*k > x && num >= k)sum += (num/k*x + (num%k)*y);else if(num < k && (Max < arr[l] || Max < arr[r]))sum += y*num;else{flag = 1;break;}}if(flag) cout << -1 << endl;else cout << sum << endl; }總結(jié)
以上是生活随笔為你收集整理的Educational Codeforces Round 91 (Rated for Div. 2) D.Berserk And Fireball(思维,暴力破解,分情况)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: admob 服务器验证_Admob广告植
- 下一篇: 假龙吟歌 - 李贺