HDU 4906 Our happy ending 解題報告(遞推)

Our happy ending

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 229    Accepted Submission(s): 66


Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

Y*wan still remember the day he first meets the devil. Now everything is done and the devil is gone. Y*wan feel very sad and suicide.

You feel guilty after killing so many loli, so you suicide too.

Nobody survive in this silly story, but there is still some hope, because this is just a silly background story during one programming contest!

And the last problem is:

Given a sequence a_1,a_2,...,a_n, if we can take some of them(each a_i can only be used once), and they sum to k, then we say this sequence is a good sequence.

How many good sequence are there? Given that each a_i is an integer and 0<= a_i <= L.

You should output the result modulo 10^9+7.
 

Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains 3 integers n, k, L.

T<=20, n,k<=20 , 0<=L<=10^9.
 

Output
For each cases, output the answer in a single line.
 

Sample Input
1 2 2 2
 

Sample Output
6
 

Author
WJMZBMR
 

Source
 
    解題報告: 多校聯合訓練第四場最後一題,隊友比賽前2分鐘A了,Orz。基本思路是枚舉前i個數能組成的數有哪些,枚舉出來的用二進制保存。比如如果前i個數能組成2,3,5,那麼用二進制表示就是0,0,1,1,0,1。這樣做的原因是避免重複。一路遞推下去就好了。

    數組開的比較大,所以儘量少memset。代碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <iomanip>
using namespace std;
#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
#define bit(n) (1LL<<(n))
typedef long long LL;
typedef unsigned long long ULL;
const LL inf=1e15;
void work();
int main()
{
#ifdef ACM
    //freopen("in.txt", "r", stdin);
#endif // ACM
    work();
}

/***************************************************/
const int maxn = bit(21);
const int mod = 1e9+7;

int id;
struct Node
{
    int v[maxn];
	int h[maxn];
	int s[maxn];
	int n[maxn];
	int size;

	void init()
	{
        ++id;
		size=0;
	}

	void push(int ss, int num)
	{
		int i = ss;

		if(v[i] == id)
		{
			n[h[i]] += num;
			if(n[h[i]] >= mod)
                n[h[i]] -= mod;
		}
		else
		{
			s[size] = ss;
			n[size] = num;
			h[i] = size++;
			v[i] = id;
		}
	}
} dp[2];

void work()
{
    int T;
    scanf("%d", &T);
    fff(cas, 1, T)
    {
        int n, k, l;
        scanf("%d%d%d", &n, &k, &l);

        int now = 1, pre = 0;
        dp[now].init();
        dp[now].push(1, 1);

        LL up = bit(k+1)-1;
        int extra = 0;
        if(l > k) extra = l - k;

        ff(nn, n)
        {
            swap(now, pre);
            dp[now].init();

            ff(i, dp[pre].size)
            {
                int st = dp[pre].s[i];

                dff(j, k, 0)
                    dp[now].push((st << j) & up | st, dp[pre].n[i]);

                if(extra)
                    dp[now].push(st, (LL)dp[pre].n[i] * extra % mod);
            }
        }

        LL sum = 0;
        ff(i, dp[now].size) if(dp[now].s[i] & bit(k))
            sum += dp[now].n[i];

        sum %= mod;
        if(sum < 0) sum += mod;

        printf("%I64d\n", sum);
    }
}

發佈了227 篇原創文章 · 獲贊 13 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章