版权声明:本文为博主原创文章,不管你喜不喜欢都请在注明作者后转载~( ̄▽ ̄~) https://blog.csdn.net/C20190102/article/details/82932078
题目
题目大意
这里有 只颜色为 的史莱姆,Snuke想每种颜色的史莱姆抓一只,他直接抓颜色为 的史莱姆需要 秒,他还可以花 秒施展一个咒语,使他已经抓住的所有史莱姆的颜色加 (颜色为 的史莱姆颜色变成 ),问达成目标最少需要多少秒。
思路
如果你规定施展 次咒语,那么抓住第 只史莱姆可以通过抓住第 只、第 只、……第 只或第 只(循环计数)得到。例如,你要施展 次咒语,捉住第 只史莱姆,就有三种办法:
- 抓 号 施展咒语 施展咒语
- 施展咒语 抓 号 施展咒语
- 施展咒语 施展咒语 抓 号
所以对于第
只史莱姆,代价
,于是答案为:
枚举
,如果暴力计算
,时间复杂度
。
想想可以发现,
能递推:
做完了。
代码
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 2000
int N,X;
int Cost[MAXN+5],Change[MAXN+5][MAXN+5];
int main(){
scanf("%d%d",&N,&X);
for(int i=1;i<=N;i++)
scanf("%d",Cost+i);
long long Ans=1ll<<60,tot=0;
for(int i=1;i<=N;i++)
tot+=Change[i][0]=Cost[i];
Ans=min(Ans,tot);//k=0的时候单独算,不然递推会越界
for(int k=1;k<N;k++){
tot=0;
for(int i=1;i<=N;i++)
tot+=Change[i][k]=min(Change[i][k-1],Cost[i-k<1?N+i-k:i-k]);//注意循环
Ans=min(Ans,1ll*k*X+tot);
}
printf("%lld",Ans);
}