记录编号 403729 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [SDOI 2009]学校食堂 最终得分 100
用户昵称 GravatarHzoi_Ivan 是否通过 通过
代码语言 C++ 运行时间 1.403 s
提交时间 2017-05-11 11:01:14 内存使用 33.69 MiB
显示代码纯文本
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1005
#define inf 1061109567
#define f(i,j,k) f[i][j][k+8]
using namespace std;
int bit[10],t[N],b[N],f[N][1<<9][17],n;
//f(i,j,k)表示从左往右数第一个未满足的为i,从第i个往后7位的集合为s ,上次买第i+k个
//刷新世界观。。。。。。 
int spend(int x,int y)
{
    if(x==0) return 0;
    return t[x]^t[y];
}
int main()
{
    freopen("dining.in","r",stdin);
    freopen("dining.out","w",stdout);
    int tt;
    bit[0]=1;
    for(int i=1;i<=9;i++) bit[i]=bit[i-1]<<1;
    scanf("%d",&tt);
    while(tt--)
    {
      scanf("%d",&n);
      for(int i=1;i<=n;i++)
        scanf("%d%d",&t[i],&b[i]);
      memset(f,0x3f,sizeof(f));
      f(1,0,-1)=0;
      for(int i=1;i<=n;i++)
        for(int j=0;j<bit[8];j++)
          for(int k=-8;k<=7;k++)
            if(f(i,j,k)<inf)
            {
              if(j&1)
                f(i+1,j>>1,k-1)=min(f(i+1,j>>1,k-1),f(i,j,k));
              else{
                int lim=inf;
                for(int l=0;l<=7;l++)
                  if(!(j&bit[l])){
                    if(i+l>lim) break;
                    lim=min(lim,i+l+b[i+l]);
                    f(i,j|bit[l],l)=min(f(i,j|bit[l],l),f(i,j,k)+spend(i+k,i+l));
                  }
              }
            }
        int ans=inf;
        for(int i=-8;i<=7;i++)
          ans=min(ans,f(n+1,0,i));
        printf("%d\n",ans);
    }
    //while(1);
    return 0;
}