zoukankan      html  css  js  c++  java
  • 2017省夏令营Day6

    题解:区间dp,f[i][j]表示区间[i,j]的狼全部消灭的最小代价,设k为i、j间任意一点(i<=k<=j),且第k只狼被最后消灭,显然,区间总代价即可被我们划分成[i,k-1]和[k+1,j]两部分,我们可以假设他们已知,于是求得两区间代价和再加上消灭第k只狼的代价就能求得区间[i,j]的总代价.

    状态转移方程:f[i][j]=f[i][k-1]+f[k+1][i]+a[k]+b[i-1]+b[j+1]。

    PS:注意初始化时i要从0开始枚举,且若j<i时f值为0。

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define INF 0x7fffffff
     5 using namespace std;
     6 int n,a[405],b[405],f[405][405],g[405][405];
     7 int main()
     8 {
     9     freopen("wolf.in","r",stdin);
    10     freopen("wolf.out","w",stdout);
    11     scanf("%d",&n);
    12     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    13     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    14     for(int i=0;i<=n;i++)
    15         for(int j=i;j<=n;j++){
    16             if(i==j) f[i][j]=a[i]+b[j-1]+b[j+1];
    17             else f[i][j]=INF;
    18         }
    19     for(int l=1;l<n;l++)
    20         for(int i=1;i+l<=n;i++){
    21             int j=i+l;
    22             for(int k=i;k<=j;k++)
    23                 f[i][j]=min(f[i][j],f[i][k-1]+f[k+1][j]+a[k]+b[i-1]+b[j+1]);
    24         }
    25     printf("%d",f[1][n]);
    26     return 0;
    27 }

    -----------------------------------------------------------华丽的分割线---------------------------------------------------------------------

    题解:首先,我们预处理1-88的斐波那契数列 f,可以推出一条规律:如果只有第i个数为答案,答案数为(i+1)/2,如果不保留这个数(此位为0),答案为(i-1)/2(“例子见下“*”)

    我们从大到小枚举斐波那契数,如果f[i]比n小那么就把i存入a数组并把n-f[i],a[i]表示第i个1所在斐波那契数列第几项,于是得出一个像二进制的01串,我们就可以从低位向高位dp。

    状态转移方程:①g[i][1]=g[i-1][0]+g[i-1][1](如果第i个1还为1,那么加入这个点对答案无影响,直接转移即可)

    ②g[i][0]=g[i-1][1]*(a[i]-a[i-1]-1)/2+g[i-1][0]*(a[i]-a[i-1])/2 (如果第i个1变成0,表明第i个1变成了前2项的和并继续向前拓展,统计答案方法如上,但是要注意如果前一个1还为1统计答案时区间长度-1,因为前一个1的位置不能用于统计)

    初始化:g[1][1]=1,g[1][0]=(a[1]-1)/2;

    *:若斐波那契数列第5项为1,可以把第5项改为0,并把3、4两项改为1,第4项无法再修改,可把第3项改为0,并把1、2项修改为1,总答案数为(5+1)/2=3;若不包含第5项(为0),答案数为(5-1)/2=2;

    代码如下:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 long long n,f[90],a[90],g[90][2];
     7 int main()
     8 {
     9     freopen("fibonacci.in","r",stdin);
    10     freopen("fibonacci.out","w",stdout);
    11     f[1]=1; f[2]=2;
    12     for(int i=3;i<=88;i++) f[i]=f[i-1]+f[i-2];
    13     int T; scanf("%d",&T);
    14     while(T--){
    15         scanf("%lld",&n);
    16         int cnt=0;
    17         for(int i=88;i>=1;i--)
    18             if(f[i]<=n){n-=f[i],a[++cnt]=1LL*i;}
    19         reverse(a+1,a+cnt+1);
    20         g[1][1]=1;
    21         g[1][0]=(a[1]-1)>>1;
    22         for(int i=2;i<=cnt;i++){
    23             g[i][1]=g[i-1][0]+g[i-1][1];
    24             g[i][0]=((a[i]-a[i-1]-1)>>1)*g[i-1][1]+((a[i]-a[i-1])>>1)*g[i-1][0];
    25         }
    26         printf("%lld
    ",g[cnt][0]+g[cnt][1]);
    27     }
    28     return 0;
    29 }

     

  • 相关阅读:
    SpringBoot2.x整合JDBC及初始化data.sql和schema.sql脚本
    CentOS7安装docker以及错误解决
    Maven的scope属性作用域范围
    (转)排序算法之简单选择排序
    系统开发博客专栏
    IDEA启动报错Plugin Error Problems found loading plugins的解决办法
    Promise函数的使用
    (转)排序算法之希尔排序
    .net Core AJAX使用Header传递参数,以JsonResult返回信息
    MVC 扩展RadioButtonListFor和CheckBoxListFor
  • 原文地址:https://www.cnblogs.com/Beginner-/p/7222966.html
Copyright © 2011-2022 走看看