#212. 矩阵

输出时忘记%lld+打错模数=自爆

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define ll long long
#define db double
#define mkp(x,y) make_pair(x,y)
#define pii pair<int,int>
#define X first
#define Y second
const int N=130;
const ll MOD=100000000000000000LL;
int n,a,b,c,S[N],SS[N];
ll f[N][N][N];
void add(ll &x,ll y){
	x+=y;if(x>=MOD)x-=MOD;
}
int main(){
	scanf("%d%d%d%d",&n,&a,&b,&c);
	int h,i,j,k,i1,j1,k1;f[0][0][0]=1;
	rep(h,1,n){
		scanf("%d",&S[h]);SS[h]=SS[h-1]+S[h];
	}
	if(SS[n]!=a+b+c){
		puts("0");return 0;
	}
	rep(h,1,n)
		per(i,S[h],0)
			per(j,S[h]-i,0)
				per(i1,min(a-i,SS[h-1]),0)
					per(j1,min(b-j,SS[h-1]-i1),0)
						add(f[h][i1+i][j1+j],f[h-1][i1][j1]);
	printf("%lld\n",f[n][a][b]);
	return 0;
}

这个O(n^5)的代码在simpleoj上跑得飞快,直接A掉。

然后考虑优化。

使用前缀和,将所有对f[h][i][j]有贡献的f[h-1][i1][j1]搞成前缀和。这些i1、j1满足以下条件:

这张图告诉我们,用g[h][k]来存k=i+j时有贡献的f[h-1][i1][j1]的和。转移时只要加入斜斜的那一条就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值