T1、
原本以为是水题的,但是题目里有这么一句话”不模1e9+7“。。。。
可以注意到上下左右都要求单调增,那么状态就很好确定了
f[i][j]表示第一行放了前i个格子,第二行放了前j个格子,并且这些数都是小于等于i+j的
转义很好写:f[i][j]可以推给f[i+1][j]和f[i][j+1]。需要时时保证i>j
另外注意此处格子是否可放。
由于不取模,需要用高精。但是实现只有0.2s
——卡常!
最后还是被卡了20分——本机测试不超时的
订正的时候发现用long long压18位居然就能过了,而9位int死活不过。。。。
还有有些人用这个不算开挂吗? __attribute__((optimize("O2")))
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const long long Mod = (1e18);
int a[2][1005];
int n,i,j;
struct BITINT{
int h;
long long a[40];
BITINT operator +(const BITINT &x) const
{
if (h==0) return x;
BITINT ret;
memset(ret.a,0,sizeof(ret.a));
ret.h = max(h, x.h);
for (int i=0;i<ret.h||ret.a[i+1]>0;i++)
{
ret.a[i] += a[i]+x.a[i];
while (ret.a[i]>=Mod)
ret.a[i+1]++, ret.a[i]-=Mod;
}
while (ret.a[ret.h]>0) ret.h++;
//for (int i=ret.h;i<70;i++) ret.a[i]=0;
return ret;
}
void print(){
if (h==0) {printf("0\n");return;}
printf("%lld",a[h-1]);
for (int i=h-2;i>=0;i--){
long long x = Mod/10;
if (a[i]==0) {printf("000000000000000000");continue;}
while (a[i]<x) {printf("0");x/=10;}
printf("%lld",a[i]);
}
printf("\n");
}
} f[1005][1005];
int main(){
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[0][i]);
for (i=1;i<=n;i++)
scanf("%d",&a[1][i]);
f[0][0].h = f[0][0].a[0] = 1;
for (i=0;i<=n;i++)
for (j=0;j<=i;j++)
if (f[i][j].h>0){
if (i<n && (a[0][i+1]==0 || a[0][i+1]==i+j+1))
f[i+1][j] = f[i+1][j] + f[i][j];
if (j<i && (a[1][j+1]==0 || a[1][j+1]==i+j+1))
f[i][j+1] = f[i][j+1] + f[i][j];
}
f[n][n].print();
return 0;
}
T2、
shtsc2011的原题。
凸包+旋转卡壳,脑补脑补就知道了。。。。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algori