算法第三章作业

1. “挖地雷”动态规划分析:

1.1 递归方程式:

当 i=n 时,f[n]=w[n];

当 i>0 && i<n 时,f[i]=max{f[j]}+w[i],其中,j满足条件a[i][j]=true。

1.2 给出填表法中表的维度、填表范围和填表顺序:

填表维度为一维,两个数组,即f和c数组,f从第n个往前填,同时将k地窖是i地窖的目标后继点以c[i]=k的形式保存下来;

1.3 分析该算法的时间和空间复杂度:

因为只需要填一维表所以时间复杂度为O(N),用了一个二维数组a[i][j]来保存i,j之间的关系,故空间复杂度为O(N^2)。

2. 对动态规划算法的理解:

DP最大的特点就是对重复子问题的处理,其他的同分治法处理思路类似,都是转化为对最优子问题的求解。

3. 结对编程情况:

挺好的,一开始存在一些思路上的问题,经过讨论都能克服。

代码展示:

#include<iostream>
#include<cstring>
using namespace std;

int main()
{
    long f[201]={0},w[201],c[201]={0};
    bool a[201][201]={0};
    long i,j,n,x,y,l,k,max;
    while(cin>>n)
    {
        memset(f,0,sizeof(f));
        memset(w,0,sizeof(w)); 
        memset(c,0,sizeof(c)); 
        memset(a,false,sizeof(a));
        for(i=1;i<=n;i++) 
          cin>>w[i];  //输入每个地窖中的地雷数 
        do
        {
            cin>>x>>y;
            if((x!=0)&&(y!=0)) a[x][y]=true;
        }
        while((x!=0)&&(y!=0));
        f[n]=w[n];  //从后面的f[n]往前逐个找出所有的f[i]
        for(i=n-1;i>=1;i--)
        {
            l=0;k=0;//l要置零,很重要
            for(j=i+1;j<=n;j++) 
            if((a[i][j])&&(f[j]>l)) 
            {
                l=f[j]; k=j;
            }
            f[i]=l+w[i]; //保存从第i个地窖起能挖到最大地雷数
            c[i]=k;      //k地窖是i地窖最优路径的后继点 
        }
        k=1;
        for(j=2;j<=n;j++) if(f[j]>f[k]) k=j;
        max=f[k];
        cout<<k;
        k=c[k];
        while(k!=0) 
        {
            cout<<"-"<<k; k=c[k];
        }
        cout<<endl;
        cout<<max<<endl;
    }
    return 0;
}

因为只需要填一维表所以时间复杂度为O(N),用了一个二维数组a[i][j]来保存i,j之间的关系,故空间复杂度为O(N^2)。
posted @ 2020-10-30 08:11  莫若以明8848  阅读(101)  评论(0编辑  收藏  举报