code1043 方格取数

第一次走用dfs枚举每种情况,第二次走用dp求剩下的最大值

设一个点集q用来保存有价值的点,排序,在最后加一个终点:x=m+1,y=m+1,v=0  //m是矩阵长宽

因为v=0的点是没有意义的,所以忽略它们,用q进行dfs

设当前点在q中的下标为p,已经积累的分数为score:

for(int i=p+1;i<=n+1;i++){
    if(q[i].y>=q[p].y){//可以到达 
        a[q[i].x][q[i].y]=0;
        dfs(i,score+q[i].v);
        a[q[i].x][q[i].y]=q[i].v;
    }
}

当p=n+1时,到了终点(n是有价值点的个数,n+1为最后添加的终点)

在残缺的a中dp找到第二次的最大价值,更新ans即可

 

代码如下:

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

struct Point{
    int x,y;
    int v;
}q[105];
bool cnt(Point c,Point d){
    return c.x<d.x || (c.x==d.x && c.y<d.y);
}
int n,m;//m是边长,n是有值的点的个数 
int a[15][15];
int d[15][15];
int ans=0; 

int dp(){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=m;j++){
            d[i][j]=max(d[i-1][j],d[i][j-1])+a[i][j];
        }
    }
    return d[m][m];
}

void dfs(int p,int score){
    if(p==n+1){
        int c=dp();
        if(ans<c+score)ans=c+score;
        return;
    }
    for(int i=p+1;i<=n+1;i++){
        if(q[i].y>=q[p].y){//可以到达 
            a[q[i].x][q[i].y]=0;
            dfs(i,score+q[i].v);
            a[q[i].x][q[i].y]=q[i].v;
        }
    }
}

int main(){
    cin>>m;
    for(n=1;true;n++){
        cin>>q[n].x>>q[n].y>>q[n].v;
        if(q[n].x==0){n--;break;}
        a[q[n].x][q[n].y]=q[n].v;
    }
    sort(q+1,q+n+1,cnt);
    q[n+1].x=m+1;q[n+1].y=m+1;q[n+1].v=0;//终点 
    dfs(0,0);
    cout<<ans<<endl;
    
    return 0;
} 

如果你看着那个a和q有点重复不爽,可以试着直接在q上dp,这样就可以省去a了

 

ps:code上用operator为什么编译不过去!!求解!!

posted @ 2016-05-05 22:27  FuTaimeng  阅读(230)  评论(0编辑  收藏  举报