noip 乌龟棋

滚动数组

//图论?因为只有四种颜色,因此,一个点连四条边
//数据保证到达终点时刚好用光 MM 张爬行卡片。??这就比较麻烦了
//回忆之前做过的搜索题
//f[i][j],j表示已经用了几张牌了
//表示每张牌还有几张f[][p][q][u][v]
//begin
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[352],b,f[5][41][41][41][41];///////////空间超了。。 
int p,q,u,v; 
int main()
{
//  freopen("tortoise8.in","r",stdin);

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int j=1;j<=m;j++)
    {
        scanf("%d",&b);
        if(b==1)
            p++;
        else if(b==2)
            q++;
        else if(b==3)
            u++;
        else
            v++;
    }
    memset(f,0x80,sizeof f);
    f[1][v][u][q][p]=a[1];
//  cout<<v<<","<<u<<","<<q<<","<<p<<endl;
    //滚动数组 ,那结果是什么呢? 
    for(int i=2;i<=n;i++)
        for(int vi=v;vi>=0;vi--)
            for(int ui=u;ui>=0;ui--)
                for(int qi=q;qi>=0;qi--)
                    for(int pi=p;pi>=0;pi--)
                    {
                        if(i-4>=1 && vi+1<=v)
                            f[i%5][vi][ui][qi][pi]=max(f[i%5][vi][ui][qi][pi],f[(i-4)%5][vi+1][ui][qi][pi]+a[i]);       
                        if(i-3>=1 && ui+1<=u)
                            f[i%5][vi][ui][qi][pi]=max(f[i%5][vi][ui][qi][pi],f[(i-3)%5][vi][ui+1][qi][pi]+a[i]);
                        if(i-2>=1 && qi+1<=q)
                            f[i%5][vi][ui][qi][pi]=max(f[i%5][vi][ui][qi][pi],f[(i-2)%5][vi][ui][qi+1][pi]+a[i]);
                        if(i-1>=1 && pi+1<=p)
                            f[i%5][vi][ui][qi][pi]=max(f[i%5][vi][ui][qi][pi],f[(i-1)%5][vi][ui][qi][pi+1]+a[i]);               
//                          cout<<i<<","<<vi<<","<<ui<<","<<qi<<","<<pi<<","<<f[i%5][vi][ui][qi][pi]<<endl; 
                    } //f[2][0][1][1][0]

    cout<<f[n%5][0][0][0][0]<<endl;     
}
//图论?因为只有四种颜色,因此,一个点连四条边
//数据保证到达终点时刚好用光 MM 张爬行卡片。??这就比较麻烦了
//回忆之前做过的搜索题
//f[i][j],j表示已经用了几张牌了
//表示每张牌还有几张f[][p][q][u][v]
//begin
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[352],b,f[41][41][41][41];///////////空间超了。。 
int p,q,u,v; 
int main()
{
//  freopen("tortoise10.in","r",stdin);

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int j=1;j<=m;j++)
    {
        scanf("%d",&b);
        if(b==1)
            p++;
        else if(b==2)
            q++;
        else if(b==3)
            u++;
        else
            v++;
    }
    memset(f,0x80,sizeof f);
    f[v][u][q][p]=a[1];
//  cout<<v<<","<<u<<","<<q<<","<<p<<endl;
    //滚动数组 ,那结果是什么呢? 
//  for(int i=2;i<=n;i++)
        for(int vi=v;vi>=0;vi--)
        {   
            for(int ui=u;ui>=0;ui--)
            {
                for(int qi=q;qi>=0;qi--)
                {
                    for(int pi=p;pi>=0;pi--)
                    {
                        int i=(v-vi)*4+(u-ui)*3+(q-qi)*2+(p-pi)*1+1;
                        if(vi+1<=v)
                            f[vi][ui][qi][pi]=max(f[vi][ui][qi][pi],f[vi+1][ui][qi][pi]+a[i]);      
                        if( ui+1<=u)
                            f[vi][ui][qi][pi]=max(f[vi][ui][qi][pi],f[vi][ui+1][qi][pi]+a[i]);
                        if( qi+1<=q)
                            f[vi][ui][qi][pi]=max(f[vi][ui][qi][pi],f[vi][ui][qi+1][pi]+a[i]);
                        if(pi+1<=p)
                            f[vi][ui][qi][pi]=max(f[vi][ui][qi][pi],f[vi][ui][qi][pi+1]+a[i]);              
//                          cout<<i<<","<<vi<<","<<ui<<","<<qi<<","<<pi<<","<<f[vi][ui][qi][pi]<<endl; 
                    } //f[2][0][1][1][0]
                }       
            }               
        }               
    cout<<f[0][0][0][0]<<endl;      
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值