您的位置:首页 > 其它

【JZOJ 5393】【NOIP2017提高A组模拟10.5】Snake vs Block

2017-10-05 22:13 471 查看

Description





Solution

题目的描述极其辣鸡,只能往下走,

设DP,f[I][i][j][l],表示在第I层,区间i~j中,蛇的长度为k,最大的分数为多少,

转移显然,记得开滚动,

别忘了区间DP啊!!!!

复杂度:O(n∗15∗10000)

Code

#include <cstdio>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=201;
int read(int &n)
{
char ch=' ';int w=1;n=0;
for(;ch!='-'&&(ch<'0'||ch>'9');ch=getchar());
if(ch=='-')ch=getchar(),w=-1;
for(;ch<='9'&&ch>='0';ch=getchar())n=n*10+ch-48;
return n=n*w;
}
int n,m,ans;
int a
[5];
int f[5][5][10001];
int g[5][5][10001];
int sum
;
bool az
[5];
int main()
{
freopen("snakevsblock.in","r",stdin);
freopen("snakevsblock.out","w",stdout);
int q,w;
sum[0]=4;
read(n);
fo(i,1,n)
{
sum[i]=sum[i-1];
fo(j,0,4)if(read(a[i][j])>0)sum[i]+=a[i][j];
}
read(m);
fo(i,1,m)read(q),read(w),az[q][w-1]=1;
g[2][2][4]=1;
fo(I,1,n)
{
fo(i,0,4)
if(a[I][i]>=0)fo(k,0,sum[I])f[i][i][k+a[I][i]]=g[i][i][k];
else fo(k,-a[I][i],sum[I])if(g[i][i][k])f[i][i][k+a[I][i]]=g[i][i][k]-a[I][i];
fo(IJ,0,3)
fo(i,0,4-IJ)
{
int j=i+IJ;
if(j<4&&!az[I][j])
if(a[I][j+1]>=0)fo(k,0,sum[I])f[i][j+1][k+a[I][j+1]]=max(f[i][j+1][k+a[I][j+1]],f[i][j][k]);
else fo(k,-a[I][j+1],sum[I])if(f[i][j][k])f[i][j+1][k+a[I][j+1]]=max(f[i][j+1][k+a[I][j+1]],f[i][j][k]-a[I][j+1]);
if(i&&!az[I][i-1])
if(a[I][i-1]>=0)fo(k,0,sum[I])f[i-1][j][k+a[I][i-1]]=max(f[i-1][j][k+a[I][i-1]],f[i][j][k]);
else fo(k,-a[I][i-1],sum[I])if(f[i][j][k])f[i-1][j][k+a[I][i-1]]=max(f[i-1][j][k+a[I][i-1]],f[i][j][k]-a[I][i-1]);
}
fod(IJ,4,0)
fo(i,0,4-IJ)
{
int j=i+IJ;
fo(k,0,sum[I])
{
g[i][j][k]=f[i][j][k];f[i][j][k]=0;
if(i)g[i][j][k]=max(g[i][j][k],g[i-1][j][k]);
if(j<4)g[i][j][k]=max(g[i][j][k],g[i][j+1][k]);
}
}
}
fo(i,0,4)fo(k,0,sum
)ans=max(ans,g[i][i][k]-1);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: