加强版密码锁
分析:
暴力枚举肯定超时,考虑dp。
f[i][j]表示将第i个拨盘,拨成j这个数字所需要的代价(时间)。
寻找子问题。肯定是f[i-1][k]+。。。。
肯定是去看上一个拨盘拨到数字k所需要的最短时间+我这个i拨盘拨到数字j所需要的最短时间,两个一加就是f[i][j]
考虑k的范围
首先第1个拨盘,最起码是0,第二个拨盘最起码是1,第三个拨盘最起码是2,那么第n个拨盘最起码是n-1.所以k=第i-1个拨盘-1,=i-2;
因为我是j,因为是严格递增序列,所以k最大只能为j-1;
考虑j的范围
j就是我们要拨成的那个数字。因为第n个拨盘最起码是n-1,所以j最小是i-1。因为严格递增序列,你不能最大一下到99,不然后面的人就没有位置了,所以要留位置。当前是第i个拨盘,后面还有n-i个,所以j最大为99-(n-i)
Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,a[105];
ll ans=1<<30;
ll f[105][105];
ll dj(int x,int y)//把a[x]拨成y所需要的代价(时间)
{
int k=min(abs(a[x]-y),min(100+y-a[x],100+a[x]-y));
return k*k;
}
int main()
{
cin>>n>>a[1];
for(int i=2;i<