zoukankan      html  css  js  c++  java
  • 动态规划1

    递推

    无后效性,最优子结构

    -》状态转移方程     -》   注意初始化 (边界值) -》注意枚举顺序(完全背包第二维从小到大,01背包从大到小,区间先长度再左)

    LIS接上之前最优解,LCS,背包问题(01背包,完全背包,分组背包,依赖性问题)

    状态压缩,树形dp

    看过最好的一篇讲解动态规划的

    https://mp.weixin.qq.com/s/15HSidWyGg5eN--ICNNjFg

    微信里的一篇文章。看完之后,基本的动态规划思想就懂了,有特点的dp需要再学习,剩下的就要刷题了。


    Vijos / 题库 /

    过河

    数据过大,状压;
    #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define maxn 1000001 int a[maxn],d[maxn],v[maxn],s,t; int main() { int l,m,x; cin>>l>>s>>t>>m; memset(d,0x7f7f7f7f,sizeof(d)); for(int i=1;i<=m;i++) cin>>x,a[x]=1; v[0]=1,d[0]=0; for(int i=1;i<=l;i++) { for(int j=0;j<i;j++) { if(i-j<s||i-j>t||!v[j]) continue; v[i]=1; if(a[i]){ d[i]=min(d[i],d[j])+1; } else d[i]=min(d[i],d[j]); } } cout<<d[l]; return 0; }

    Vijos / 题库 /

    清帝之惑之顺治

    先自顶向上,随机选取某个点i,i是由哪些点转移过来。
    刚开始没想那么多,直接顺序枚举图,但结果不对,
    因为如果map[i][j]的高度小于四周,四周其实目前还没有修改,仍是初始状态
    等到四周的值都改了之后,又回不到该点
    #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define maxn 601 int ma[maxn][maxn],d[maxn][maxn]; struct m{ int x,y; int hight; }g[251000]; bool compare(m i,m j) { return i.hight>j.hight; }//将图上的高度进行排序 int main() { int r,c,ans=0,k=0; cin>>r>>c; for(int i=1;i<=r;i++) for(int j=1;j<=c;j++){ cin>>ma[i][j]; g[++k].x=i,g[k].y=j; g[k].hight=ma[i][j]; d[i][j]=1;//注意初始化,刚开始没考虑,结果就过了两个测试点 } sort(g+1,g+1+k,compare); for(int i=1;i<=k;i++)//枚举,上下左右 { int w=g[i].x,u=g[i].y; if(ma[w][u]>ma[w-1][u]&&(w-1)>0) { d[w-1][u]=max(d[w][u]+1,d[w-1][u]); } if(ma[w][u]>ma[w+1][u]&&w+1<=r) { d[w+1][u]=max(d[w][u]+1,d[w+1][u]); } if(ma[w][u]>ma[w][u-1]&&u-1>0) { d[w][u-1]=max(d[w][u]+1,d[w][u-1]); } if(ma[w][u]>ma[w][u+1]&&u+1<=c) { d[w][u+1]=max(d[w][u]+1,d[w][u+1]); } } for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) ans=max(ans,d[i][j]); cout<<ans; return 0; }

     最大子矩阵和问题

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<cstring>
    using namespace std;
    #define max2 1111
    #define rson ((pos)*2+1)
    #define lson ((pos)*2)
    int dp[max2],c[max2],ans=0,sum,line1[max2],line[max2],a[max2][max2],n,m;
    int main()
    {
        int pos1,pos2,lin1=0x3f3f3f3f,lin2=0;//pos1,pos2分别代表子矩阵起始行和末位行,lin1,lin2代表子矩阵列号
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            cin>>a[i][j];
        for(int i=1;i<=n;i++)//方法,将二维矩阵转换成一维,对于r~l行,其中每一列的元素和为b[j],此时该子矩阵的最大和相当于最大连续列的和相加即求最大连续子序列
        {
            memset(c,0,sizeof(c));
            for(int j=i;j<=n;j++){//i为子矩阵起始行,j为子矩阵末尾行
                for(int k=1;k<=m;k++)//对于行号为i,j大小的子矩阵,对其列的和进行计算
                c[k]+=a[j][k];
                int dp=0;
                for(int h=1;h<=m;h++)//连续列的最大值
                {
                    if(dp>0){dp+=c[h],line1[h]=1;}
                    else{memset(line1,0,sizeof(line1)),dp=c[h];line1[h]=1;}
                    if(ans<dp){
                        ans=dp;
                        lin1=0x3f3f3f3f,lin2=0;
                        for(int u=1;u<=m;u++) if(line1[u]) lin1=min(lin1,u),lin2=max(lin2,u);;
                    }
                }
                if(sum<ans){
                        sum=ans;
                    pos1=i,pos2=j;
                }
                memset(line,0,sizeof(line));
            }
        }
       cout<<sum<<endl;
       cout<<pos1<<' '<<pos2<<' '<<lin1<<' '<<lin2;//输出该子矩阵的行号和列号
        return 0;
    }
  • 相关阅读:
    JavaScript实现类的private、protected、public、static以及继承
    OSS网页上传和断点续传(STSToken篇)
    OSS网页上传和断点续传(OSS配置篇)
    Linq sum()时遇到NULL
    SQLSERVER事务日志已满 the transaction log for database 'xx' is full
    笔记本高分辨软件兼容问题,字体太小或模糊
    H5上传图片之canvas
    An error occurred while updating the entries. See the inner exception for details.
    无限级结构SQL查询所有的下级和所有的上级
    SQLserver 进程被死锁问题解决
  • 原文地址:https://www.cnblogs.com/Showend/p/12359310.html
Copyright © 2011-2022 走看看