• sdut2878 环形依赖的DP(高斯消元,剪枝后的模板


    这题的状态是循环依赖的有环。。

    之前一道概率DP,类似有环。。但是它是可以消掉的

    比如dp[i]=0.3*dp[i+1]+0.2*dp[i+2]+0.5*dp[i];

    完全可以变成,0.5*dp[i]=0.3*dp[i+1]+0.2*dp[i+2]

    然后把系数除过去就好了,

    然而这个题是,dp[i]=0.5*dp[i+1]+0.5*dp[i-1]+1;

    这个+1是什么意思呢,dp[i]->要到i+1,i-1任意两个状态之一,一定要付出1步的代价!

    想一想背包问题。。类似的,

    然后你会发现dp[i]还没递归完。。dp[i-1]和dp[i+1]又跑回来找它了。。。这不可能DP得出来

    所以这个题正确的消环方法是,高斯消元

    高斯消元我还不太会写。。待我学习一波回来写一写!

    (学了高斯消元回来补辣!

    我博客里的模板正常用是会TLE的!

    需要剪枝!

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cmath>
     5 #include <cstring>
     6 using namespace std;
     7 const double EPS=1e-8;
     8 int n,p;double A[1005][1005];
     9 double x[1005];
    10 int Gauss(){
    11     for(int i=0;i<n;++i){
    12         int pivot=i;
    13         for(int j=i+1;j<n;++j)if(abs(A[j][i]>abs(A[pivot][i]))) pivot=j;
    14        if(pivot!=i) for(int k=0;k<n;++k) swap(A[i][k],A[pivot][k]);
    15         if(abs(A[i][i])<EPS) return 0;
    16         for(int j=i+1;j<=n;++j) A[i][j]/=A[i][i];
    17         for(int j=i+1;j<n;++j)
    18             if(j!=i) {
    19                 if(abs(A[j][i])<EPS) continue;
    20                 for(int k=i+1;k<=n;++k) A[j][k]-=A[j][i]*A[i][k];
    21             }
    22     }
    23     for(int i=0;i<n;++i) x[i]=A[i][n];  double ans;
    24     for(int i=n-1;i>=0;--i){
    25         ans=x[i];
    26         for(int j=i+1;j<n;++j) ans-=A[i][j]*x[j];x[i]=ans;
    27     }
    28     return 1;
    29 }
    30 int main(){
    31     int T;scanf("%d",&T);
    32     while(T--){
    33         scanf("%d%d",&n,&p);
    34         //构造系数矩阵
    35         memset(A,0,sizeof(A));
    36         for(int i=0;i<n;++i){
    37             if(i==p) {
    38                 A[i][i]=1;A[i][n]=0;
    39                 continue;
    40             }
    41             A[i][i]=1;A[i][(i-1+n)%n]=-0.5;
    42             A[i][(i+1)%n]=-0.5;A[i][n]=1;
    43         }
    44         Gauss();
    45         printf("%.4f
    ",x[0]);
    46     }
    47     return 0;
    48 }

    14行和19行是剪枝的地方,不减的话这题最高1000^3还是会T的

  • 相关阅读:
    什么是https?
    简单的理解依赖注入
    Java多线程学习笔记——信号量的使用
    算法学习之一,排序算法
    MySQL中自己不太常用的命令
    如何判断链表相交
    windows&cmd常用命令&快捷键
    ubuntu桌面安装常用软件&及常见问题
    redis在windows上安装+RedisDesktopManager
    windows php5.4,5.6,7.X添加redis扩展
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6574762.html
Copyright © 2020-2023  润新知