学习心得(code)

superlong@CoreCoder

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  74 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

公告

文字可能放在http://blog.csdn.net/superlong100,此处存放代码

常用链接

留言簿(4)

我参与的团队

搜索

  •  

最新随笔

最新评论

  • 1. re: Poj 1279
  • 对于一个凹多边形用叉积计算面积 后能根据结果的正负来判断给的点集的时针方向?
  • --bsshanghai
  • 2. re: Poj 3691
  • 你写的这个get_fail() 好像并是真正的get_fail,也是说fail指向的串并不是当前结点的子串。为什么要这样弄呢?
  • --acmer1183
  • 3. re: HDU2295[未登录]
  • 这个是IDA* 也就是迭代加深@ylfdrib
  • --superlong
  • 4. re: HDU2295
  • 评论内容较长,点击标题查看
  • --ylfdrib
  • 5. re: HOJ 11482
  • 呵呵..把代码发在这里很不错..以后我也试试...百度的编辑器太烂了....
  • --csuft1

阅读排行榜

评论排行榜

#include <stdio.h>
#include 
<string.h>

const int N = 500005;

typedef 
long long LL;

int n, m;
LL f[N], s[N];
int que[N], C[N];

inline LL min(LL a, LL b) {
return a < b ? a : b;}
inline LL max(LL a, LL b) {
return a > b ? a : b;}

inline LL G(
int j, int k) {return s[j]*s[j]-s[k]*s[k] + f[j] - f[k];}

inline LL g(
int j, int k) {return 2*(s[j]-s[k]);}

int main() {
    
while( scanf("%d %d"&n, &m) != EOF ) {
        s[
0= 0;
        
for(int i = 1; i <= n; i ++) {
            scanf(
"%d", C + i);
            s[i] 
= s[i-1+ C[i];
        }
        f[
0= 0;
        
int head = 0, tail = 0;
        que[
0]= 0;
        que[
++tail] = 1; f[1= s[1]*s[1+ m;
        
for(int i = 2; i < n  + 1; i ++) {
            
while( head < tail && s[i] * g(que[head+1], que[head]) >= G(que[head+1], que[head]) ) 
                head 
++;
            f[i] 
= f[que[head]] + (s[i]-s[que[head]])*(s[i]-s[que[head]]) + m;
            
while( head < tail && G(que[tail], que[tail-1])*g(i, que[tail]) >= 
                                  G(i, que[tail])
*g(que[tail], que[tail-1]) ) tail --;
            que[
++tail]= i;
        }
        printf(
"%I64d\n", f[n]);
    }
}


/*
dp[i]= min{ dp[j]+ ( sum[i]- sum[j] )* ( sum[i]- sum[j] )+ m } ( i< j );
假设 j> k, 对于 i, 要使决策 j 优于决策 k
则有 dp[j]+ ( sum[i]- sum[j] )* ( sum[i]- sum[j] )+ m<
dp[k]+ ( sum[i]- sum[k] )* ( sum[i]- sum[k] )+ m
得到 dp[j]+ sum[j]* sum[j]- dp[k]- sum[k]* sum[k]<
2* sum[i]* ( sum[j]- sum[k] )
令 F[j,k]= (dp[j]+sum[j]*sum[j]-dp[k]-dp[k]*sum[k])/(2*(sum[j]-sum[k]))
对于当前 i, j 比 k 优等价于 F[j,k]< sum[i],所以计算当前 i 的值时
可以剔除 F[j,k]< sum[i] 的 k 值。

进一步,对于 k< j< i< t
如果 F[j,k]> F[i, j]. F[i,j]与 sum[t] 有两种关系
1. F[i,j]<= sum[t] 可知 i 比 j 优
2. F[i,j]> sum[t] 得到 F[j,k]> sum[t] 同样知 k 比 j 优
综上知 j 不会是最优的
进队时, 对满足 F[j,k]> F[i,j] 条件的 i,则可以
剔除 j.
*/


posted on 2010-08-06 12:59 superlong 阅读(516) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理