code1068 乌龟棋

暴力显然不行,所以考虑dp

记f[i][j][k][l]为使用i张1,j张2,k张3,l张4所得到的最大分数。

对于每个f[i][j][k][l],都可以由i-1张1,j张2,k张3,l张4所得到,

或者i张1,j-1张2,k张3,l张4所得到,

或者i张1,j张2,k-1张3,l张4所得到,

i张1,j张2,k张3,l-1张4所得到 的最大分数,

四者取max。

当然,还需加上它当前位置的分数。

当前位置为a[i+j*2+k*3+l*4+1](初始位置是1)

 

代码如下:

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

int f[41][41][41][41];
int s[360]; 
int n,m;


int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>s[i];
    }
    
    int a,b,c,d;
    a=b=c=d=0;
    int x;
    for(int i=1;i<=m;i++){
        cin>>x;
        switch(x){
            case 1:a++;break;
            case 2:b++;break;
            case 3:c++;break;
            case 4:d++;break;
        }
    }
    
    for(int i=0;i<=a;i++){
        for(int j=0;j<=b;j++){
            for(int k=0;k<=c;k++){
                for(int l=0;l<=d;l++){
                    int& ans=f[i][j][k][l];
                    if(i>0)ans=max(ans,f[i-1][j][k][l]);
                    if(j>0)ans=max(ans,f[i][j-1][k][l]);
                    if(k>0)ans=max(ans,f[i][j][k-1][l]);
                    if(l>0)ans=max(ans,f[i][j][k][l-1]);
                    ans+=s[i+j*2+k*3+l*4+1];
                }
            }
        }
    }
    
    cout<<f[a][b][c][d];
    
    return 0;
}

 

在编写这个程序的过程中犯了一点小错误,在循环开始前把f[0][0][0][0]=s[1]

自认为考虑非常周到,把边界写上了,其实不用

在循环i=j=k=l=0的时候4个if都不进,最后ans+=s[i+j*2+k*3+l*4+1]其实已经把s[1]的值赋值给f[0][0][0][0]了,前面再画蛇添足就是错误的。

看来边界问题是一个非常有趣(坑)的问题啊...

posted @ 2016-04-26 21:53  FuTaimeng  阅读(382)  评论(0编辑  收藏  举报