https://vijos.org/p/1002
dp转移方程比较简单,不过需要优化
数组开滚动数组,否则10^9数组。。
然后就是离散化,如果连续t个值都相同,那么就跳到下一个石头位置-t
PS:f数组初始化开大一点。。我提交五六次结果是这个问题。。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdlib>
#define ms(i,j) memset(i,j,sizeof(i));
using namespace std;
int a[105];
int f[20];
int main()
{
ms(a,127);
int l,s,t,m;
scanf("%d%d%d%d", &l, &s, &t, &m);
for (int i=0;i<m;i++)
{
scanf("%d", &a[i]);
}
if (s==t)
{
int ans = 0;
for (int i=0;i<m;i++)
{
if (a[i]%t==0) ans++;
}
printf("%d\n", ans);
return 0;
}
sort(a, a+m);
ms(f, 127);
int tot = 0, now = 0, p = 0;
f[0] = 0;
for (int i=0;i<l+t;i++)
{
for (int j=s;j<=t;j++)//转移
{
f[i%t] = min(f[i%t], f[(i-j+t)%t]);
}
if (a[p]==i)//石头
{
f[i%t]++;
p++;
}
if (now==f[i%t])//记录相同
{
tot++;
} else
{
now = f[i%t];
tot = 0;
}
if (tot==t)//离散处理
{
i = min(a[p]-t,l);
}
}
int ans = 100000000;
for (int i=0;i<t;i++)
{
ans = min(ans, f[i]);
}
printf("%d", ans);
return 0;
}