• 一些关于DP的知识


      1 /*在数轴上有0-N的位置
      2 从0出发每次可以向右走
      3 2
      4 23
      5 233步*/
      6 
      7 // 1 总共的方案数
      8 
      9 f[i]=f[i-2]+f[i-23]+f[i-233];
     10 
     11         f[0]=1;
     12     for (int a=1;a<=n;a++)
     13     {
     14         if (a>=2) f[a]+=f[a-2];
     15         if (a>=23) f[a]+=f[a-23];
     16         if (a>=233) f[a]+=f[a-233];
     17     }
     18     printf("%d
    ",f[n]);
     19 
     20 // 2 考虑恰好t次到达时
     21 //dp 题 可以考虑 每多一个条件 数组就多一维;所以,开二维数组
     22 //f[i][j] 表示 用 j 步走了i种方案
     23 
     24 f[i][j]=f[i-2][j-1]+f[i-23][j-1]+f[i-233][j-1];
     25 
     26         f[0][0]=1;
     27     for (int a=1;a<=n;a++)
     28         for (int b=1;b<=t;b++)
     29         {
     30             if (a>=2) f[a][b]+=f[a-2][b-1];
     31             if (a>=23) f[a][b]+=f[a-23][b-1];
     32             if (a>=233) f[a][b]+=f[a-233][b-1];
     33         }
     34     printf("%d
    ",f[n][t]);
     35         int ans=0;
     36     for (int a=0;a<=t;a++)
     37         ans+=f[n][a]; 
     38     printf("%d
    ",ans);
     39 
     40 //  3 考虑小于t次
     41 //
     42 f[n][1]+f[n][2]+....f[n][t];
     43 
     44 //考虑最多走r步233
     45 //so 要再加一维,变成三维数组
     46 //f[i][j][k] 表示走到 i点,公用j步,走233用了k步
     47  
     48 f[i][j][k]=f[i-2][j-1][k]+ f[i-23][j-1][k]+ f[i-233][j-1][k-1];
     49 /*
     50 (N,M)的方格图
     51 从(0,0)开始
     52 只能朝右或上走
     53 问走到(N,M)的方案数*/ 
     54 
     55 //将每个点的左边点和下边点相加
     56 
     57 f[n][m]=f[n-1][m]+f[n][m-1];
     58 
     59 //考虑有k个点(x,y)不能走
     60 //定义布尔数组记录每个不能坐的点 
     61 每次设f[x][y]=0,并加以判断;
     62 
     63 //2.考虑每个坑只能掉一次
     64 if(不是坑)
     65 
     66 F[i][j][k]=f[i-1][j][k]+f[i][j-1][k];
     67 
     68 else if(是坑)
     69 
     70 F[i][j][1]=f[i-1][j][0]-f[i][j-1][0];
     71 
     72 
     73 #include<iostream>
     74 using namespace std;
     75 int main() 
     76 {
     77     int n,i,j,a[101][101];
     78     cin>>n;
     79     for (i=1; i<=n; i++)
     80         for (j=1; j<=i; j++)
     81             cin>>a[i][j];                             //输入数字三角形的值
     82     for (i=n-1; i>=1; i--)
     83         for (j=1; j<=i; j++) 
     84         {
     85             if (a[i+1][j]>=a[i+1][j+1])  
     86             a[i][j]+=a[i+1][j];     //路径选择
     87             else  a[i][j]+=a[i+1][j+1];
     88         }
     89     cout<<a[1][1]<<endl;
     90 }
     91 //************矩阵乘法*************
     92 
     93 //性质 
     94 
     95 /*乘法结合律: (AB)C=A(BC).[2] 
     96 乘法左分配律:(A+B)C=AC+BC[2] 
     97 乘法右分配律:C(A+B)=CA+CB[2] 
     98 对数乘的结合性k(AB)=(kA)B=A(kB).
     99 转置 (AB)T=BTAT.
    100 矩阵乘法一般不满足交换律*/
    101 
    102 
    103 
    104 
    105      // M1(n*m)*M2(m*k)=M2(n*k)
    106 
    107 //M1的每一行 (i) 乘以M2的每一列 (j) 所得到的 对应元素相乘的积 再相加求和 得到 M3的(i,j)处的数值
    108 
    109 //已知 M1 , M2 , 求 M3 
    110 //代码实现:
    111 
    112        for (int a=1;a<=n;a++)
    113         for (int b=1;b<=m;b++)
    114             for (int c=1;c<=k;c++)
    115                 m3[a][c]+=m1[a][b]*m2[b][c];//M1 的行 && M2 的列 组成 M3 的 坐标 ,很好理解 
    116 
    117 //a 表示 M1 的行 && M2 的行,b表示 M1 的列 ,c表示 M2 的列 ;
    118 //所以 M3 为 a 行,c 列 数组
    119 
    120  
    121 int fib(int a)
    122 {
    123     if (!a) return 0;
    124     if (a==1) return 1;
    125     if (g[a]) return f[a];
    126     g[a]=true;
    127     f[a]=fib(a-1)+fib(a-2);
    128     return f[a];
    129 }
    130  数字三角形问题,使得答案对p取模最大?
    131 
    132 
    133 F[i][j][k] 表示走到第i行第j列 使得答案模p是否可行
    134 
    135 F[i][j][k]=f[i+1][j][k-v[i][j]]
    136 Or
    137 F[i+1][j+1][k-v[i][j]]
    138 **********代码:
    139 
    140     for (int a=1;a<=n;a++)
    141         f[n][a][v[n][a]%p]=true;
    142     for (int a=n-1;a>=1;a--)
    143         for (int b=1;b<=a;b++)
    144             for (int c=0;c<p;c++)
    145                 f[a][b][c]=
    146                     f[a+1][b][(c-v[a][b]+p)%p] ||
    147                     f[a+1][b+1][(c-v[a][b]+p)%p];
    148     int ans;
    149     for (int a=p-1;a>=0;a--)
    150         if (f[1][1][a])
    151         {
    152             ans=a;
    153             break;
    154         }
    155 
    156 //***********区间DP******** 
    157 
    158 /*合并石子
    159 
    160 每次选择相邻两堆
    161 
    162 代价为两堆石子和
    163 
    164 问最小总代价
    165 
    166 
    167 (第一层for循环一定要正着写)
    168 
    169 因为后一层循环需要前一层循环的数据 */
    170 
    171 F[l][r]=min(f[l][k]+f[k+1][r]+sum[l][r])
    172 
    173 
    174 /*矩阵乘法
    175 自定义顺序
    176 使得运算次数最少*/
    177 
    178 //F[i][j] 表示搞定[I,j]的最小代价
    179 F[i][j] = min(f[i][k]+f[k][j+1]+cost(I,k,j))

    DP 骗分,All骗分
    180 /*1.样例,( 现在来说应该不行了181 182 2.搜索,( 万分爆力的枚举183 184 3.大小->贪心:( 找个尽可能科学的方法说服自己,得部分 分185 《1》每次选代价最小的两个矩阵 186 《2》 每次选最大。。。。 187 《3》手动找规律。。。。。。。 188 189 4.随机化( 听天由命吧190 Int t=clock(); 191 While(clock()-t>950) 192 { 193 Do something; }*/

    相信你会收获许多******

    想了解关于“数据结构”的知识,请于本园搜索 “数据结构” ;

  • 相关阅读:
    P1983 车站分级
    鬼知道NOI会不会成为下一个奥数
    设计模式之简单工厂模式(含样例源码下载)
    面向对象的七大设计原则(点滴的感悟与总结)
    网易笔试题 最长公共子括号序列
    网易笔试题 重排数列
    网易笔试题 游历魔法王国
    腾讯笔试题 字符移位(字符串操作)
    华为笔试题 最高分是多少(线段树)
    华为笔试题 扑克牌大小(模拟,细节处理)
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/6818699.html
Copyright © 2020-2023  润新知