标签:简单的 ima 空间 感情 状压 上下 部分 ++ 翻转
全是DP实际上发现暴力也能有部分分.......
DP......当时总是感觉不像啊
需要处理的就是枚举三角形边长可能出现的情况。因为周长在输入端时候就可以确定了,所以只需要通过枚举两条边就可以强行算出第三条边.....
所以就省空间+时间....
f[0][0] = 1;
for (int i=1; i<=n; ++i)
for(int j=half; j>=0; j--)
for(int k=j; k>=0; k--)
if(j >= d[i] && f[j-d[i]][k] || k >= d[i] && f[j][k-d[i]])
f[j][k] = 1;
查找边数的存在情况
然后就是判断是否能组成三角形与否
for (int i=half; i>=1; --i)
for (int j=i; j>=1; --j)
if (f[i][j])
f (check(i, j, tot - i - j))
ans = max(ans, area(i, j, tot - i - j));
然后就做完了.......
又是DP.......我莫得感情直接算出上下的差,然后直接计算一边。不过这个有负数的答案出现,所以要处理一下变成正数就好了...
然后再找答案就好了
for(int i=1; i<=n; i++)
for(int j=-5000; j<=5000; j++)
f[i][j+M] = min(f[i-1][j-c[i]+M], f[i-1][j+c[i]+M]+1);
for(int i=0; i<=5000; i++)
{
ans = min(f[n][i+M], f[n][-i+M]);
if(ans <= 1000)//因为n小于1000,所以最多翻转肯定是1000以内
{
printf("%d\n", ans);
break;
}
}
把自己列出的公式推导一下。
首先f[i]是作为一个结束点,f[j]是断点。
所以
然后发现可以上一波前缀和优化。
然后发现在i中,sum[i]其实是一个定值,所以可以提出来
发现只与j有关联,并且始终找最大值。
然后滚去了解了一下什么是单调队列,保证队列内数字单调,输出前面的最大值就可以了
IL ll top(int i)
{
d[i] = f[i-1] - sum[i];
while (head <= tail && d[q[tail]] < d[i]) tail--;
q[++tail] = i;
while (head <= tail && q[head] < i - k) head++;
return d[q[head]];
}
单调队列,然后用这个来找最大值
for(int i=1; i<=n; i++) f[i] = top(i) + sum[i];
这个任务并不简单
状压DP......劝退
标签:简单的 ima 空间 感情 状压 上下 部分 ++ 翻转
原文地址:https://www.cnblogs.com/rendex/p/9782562.html