生活随笔
收集整理的這篇文章主要介紹了
codeforces1457 C. Bouncing Ball
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
寫這個題寫了1h,賽后無意看見jly神的代碼只能膜拜%%%
C. Bouncing Ball
預處理從1→k1\to k1→k開始跳需要添加多少個平臺,預處從k+1→nk+1\to nk+1→n這些不難發現由于每次跳k格,只需要利用前綴和思想和前面預處理的結果即可做差求出。
然后枚舉刪除平臺的個數,例用預處理結果直接求答案。
時間復雜度O(n)O(n)O(n)
有一個dt的地方就是如何用數組存預處理結果,我們需要這樣大小為數組cnt[k][n/k]。cnt[i][j]表示從i開始向后跳j次也就是跳了jk個格子。
數組顯然不能開,這里用動態數組vector存儲
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std
;
typedef long long ll
;
typedef pair
<int,int> pii
;
const int N
=100010;int main()
{int T
=1;cin
>>T
;while(T
--){int n
,p
,k
;cin
>>n
>>p
>>k
;string s
;cin
>>s
;s
="0"+s
;ll x
,y
; cin
>>x
>>y
;ll res
=1e18;vector
<vector
<int> > cnt(k
+1,vector
<int>(n
/k
+1,0));for(int i
=1;i
<=k
;i
++)for(int j
=i
;j
<=n
;j
+=k
){if(j
!=i
) cnt
[i
][(j
-i
)/k
]=cnt
[i
][(j
-i
)/k
-1];if(s
[j
]=='0') cnt
[i
][(j
-i
)/k
]++;}for(int i
=1;i
<=n
;i
++){ll now
=y
*(i
-1);int j
=i
+p
-1;if(j
>n
) continue;int w
=(j
-1)%k
+1;int l
=(j
-w
)/k
,r
=(n
-w
)/k
;now
+=x
*cnt
[w
][r
];if(l
>0) now
-=x
*cnt
[w
][l
-1];res
=min(res
,now
);}cout
<<res
<<'\n';}return 0;
}
jly代碼
大體思路就是從后往前計算出需要從某個點向后跳需要添加平臺的個數,然后枚舉刪除平臺的個數。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std
;
typedef long long ll
;
typedef pair
<int,int> pii
;
const int N
=100010;
int main()
{int T
=1;cin
>>T
;while(T
--){int n
,p
,k
;cin
>>n
>>p
>>k
;--p
;string s
;cin
>>s
;int x
,y
;cin
>>x
>>y
;int ans
=1e9;vector
<int> dp(n
);for(int i
=n
-1;i
>=0;i
--){dp
[i
]=(s
[i
]=='0')?x
:0;if(i
+k
<n
) dp
[i
]+=dp
[i
+k
];}for(int i
=p
;i
<n
;i
++) ans
=min(ans
,(i
-p
)*y
+dp
[i
]);cout
<<ans
<<'\n';}return 0;
}
思維還是不行,別人10分鐘A的題,自己1h還差點沒過。。
要加油哦~
總結
以上是生活随笔為你收集整理的codeforces1457 C. Bouncing Ball的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。