C - Bouncing Ball
思路
看到这个题,思路很好想,就是从前往后的依次删除前面的元素,然后看每次选到的0的个数,本来写了一个暴力,结果超时了,一直在想o(n)的方法求出以点i开始,从i到~n,每次选到的数有几个0,但是发现自己不会写,没法想出来,看了大佬的代码才发现太妙了。
部分代码
for(int i=n ; i>=1 ; i--)
{
if(a[i]=='0') dp[i]=x;
if(i+k<=n) dp[i]+=dp[i+k];
}
dp[i]就表示从i开始,选到的0的贡献,可以用o(n)的时间复杂度求出来。
代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10;
char a[N];
int dp[N];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,p,k;
cin>>n>>p>>k;
for(int i=1 ; i<=n ; i++) cin>>a[i],dp[i]=0;
int x,y;
cin>>x>>y;
for(int i=n ; i>=1 ; i--)
{
if(a[i]=='0') dp[i]=x;
if(i+k<=n) dp[i]+=dp[i+k];
}
int ans=1e9;
for(int i=p ; i<=n ; i++)
{
// cout<<i<<" "<<dp[i]<<endl;
ans=min(ans,(dp[i]+(i-p)*y));
}
cout<<ans<<endl;
}
return 0;
}
总结
自己的思维能力还是太差了,想到了要怎么做,但是却发现写不出来,还是写的题太少了。