牛客練習賽41(B 666RPG)

題目傳送門

這裏呢,用的方法是dp,俗話說的好"神用dp,人用暴力",但是呢,我都不會(白嫖大佬的代碼)。


方法簡介:

首先,先const 一個maxn=666*300+5;這裏加5嘛,就只有防爆炸的作用,重要的是這個666*300,爲什麼要定義一個maxn呢,因爲,我們要開一個4*maxn大的二維數組ans[2][maxn*2+5],那麼爲什麼要開一個maxn大的數組呢?

因爲,我們需要的一個足夠大的數組來儲存我們所有可能的結果。那麼問題又來了,所有的可能結果包括到什麼程度。變看代碼,邊看註釋

 

#include<bits/stdc++.h>

using namespace std;

const int maxn=666*300+5;	//以maxn爲分界線,代表小於maxn的爲負數的結果,大於maxn爲大於0的結果 
const int mod=1e8+7;
int cur=1;
int old=0;

int ans[2][maxn*2+5];
int a[maxn];

//取模並賦值。 
void mo(int &x,int y)
{
	x=(x+y)%mod;
}

int main()
{
	int n;
	int i,j;
	
	cin>>n;
	for(i=0;i<n;++i) cin>>a[i];
	
	 
	ans[cur][maxn]=1;   //這裏是一切可能的開始,沒看懂得先看下面的。
	
	for(i=0;i<n;++i)
	{
		swap(cur,old);						//滾動數組 
		fill(ans[cur],ans[cur]+maxn*2,0);	//初始化當前的所需要更新的數組 
		for(j=-maxn;j<=maxn;++j)
		{
			if(j!=-666) mo(ans[cur][maxn+j],ans[old][maxn-j]);	//這裏表示操作B,便利所有的可能,即便是不需要的可能(比如我們上一次更新當前數組後的a[x]的值爲0代表x這個結果在更新後,沒有一個可能的值爲x) 
			if(j-a[i]>=-maxn&&j-a[i]!=666) mo(ans[cur][maxn+j],ans[old][maxn+j-a[i]]);	//這裏是操作A,原理同上 
		}
	}
	
	cout<<ans[cur][maxn-666]<<endl;
	
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章