uva1379

##uva1379这个题目主要是考察在进行状态转移过程中如何节省时间和空间的开销,在这个题目里面运用了滚动数组,使得空间节省,利用贪心节省时间和空间,在求解之前,要分析在这个dp中的状态转移,dp【date】【i】【j】【k】【l】分别表示第date天,前四天分别对应的队伍,,,在进行状态转移贪心主要运用在其休息4天方可再进行比赛,,那么我们只需要取前五名的即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define maxn 1000
#define rep(i,n)  for(int i=0;i<n;i++)
struct node {
int x;
int id;
}a[110][105];
int dp[2][6][6][6][6];
int d[300];
bool cmp(node x,node y)
{
    return x.x>y.x;
}
int n,m,g;
void solve()
{
    memset(dp,0,sizeof(dp));
    int cnt=0;
    for(int i=g;i>=1;i--)
    {
        memset(dp[cnt],0,sizeof(dp[cnt]));
              rep(j,6)
              rep(k,6)
              rep(l,6)
              rep(r,6){
              int p=d[i];
              if(p)
              {
                  int s;
                  for(s=1;s<=5;s++)//只需要到达第五大即可,,不需要继续往后面走
                  {
                      if(i>1&&a[p][s].id==a[d[i-1]][j].id)continue;
                      if(i>2&&a[p][s].id==a[d[i-2]][k].id)continue;
                      if(i>3&&a[p][s].id==a[d[i-3]][l].id)continue;
                      if(i>4&&a[p][s].id==a[d[i-4]][r].id)continue;
                      dp[cnt][j][k][l][r]=max(dp[cnt^1][s][j][k][l]+a[p][s].x,dp[cnt][j][k][l][r]);//发现第s个是可以在第i天出现的故可以进行状态转移
                  }
              }
              else
              {
                  dp[cnt][j][k][l][r]=max(dp[cnt^1][0][j][k][l],dp[cnt][j][k][l][r]);//这一天没有对手
              }
              }
              cnt^=1;
    }
    int ans=0;
              rep(j,6)
              rep(k,6)
              rep(l,6)
              rep(r,6)
              ans=max(ans,dp[cnt^1][j][k][l][r]);
              printf("%.2lf\n",double (ans/100.0));
}

int main()
{
        int t;
     //  freopen("in.txt","r",stdin);
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&g);
            for(int i=1;i<=m;i++){
                for(int j=1;j<=n;j++)
            {
                    scanf("%d",&a[i][j].x);
                    a[i][j].id=j;
            }
              sort(a[i]+1,a[i]+1+n,cmp);//进行贪心的先决条件,,必须从大带小排序
            }
            g=g+10;
            for(int i=1;i<=g;i++)
            {
                 scanf("%d",&d[i]);
            }
            solve();
        }
        return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值