P2946 [USACO09MAR]Cow Frisbee Team S(dp)

每天寫兩道dp題,2020/07/03 打卡第一天
題目鏈接

題目描述
老唐最近迷上了飛盤,約翰想和他一起玩,於是打算從他家的 NN 頭奶牛中選出一支隊伍。每隻奶牛的能力爲整數,第 ii 頭奶牛的能力爲Ri 。飛盤隊的隊員數量不能少於 11、大於NN。一支隊伍的總能力就是所有隊員能力的總和。約翰比較迷信,他的幸運數字是 FF ,所以他要求隊伍的總能力必須是 F 的倍數。請幫他算一下,符合這個要求的隊伍組合有多少?由於這個數字很大,只要輸出答案對 10^8取模的值。

輸入格式
第一行:兩個用空格分開的整數:N 和 F。
第二行到 N+1 行:第 i+1i+1 行有一個整數Ri,表示第 ii 頭奶牛的能力。

輸出格式
第一行:單個整數,表示方案數對 10^8 取模的值。

輸入輸出樣例
輸入
#1

4 5
1
2
8
2

輸出

3

用dp[i][j]表示前i個物品和模f餘數爲j時候的方法的最優解。

則狀態轉移方程爲

dp[i][j]=dp[i][j]+dp[i-1][j]+dp[i-1][(j-a[i]+f)%f];

#include<bits/stdc++.h>
#define pb push_back
#define bp __builtin_popcount
using namespace std;
typedef unsigned long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e3 + 100;
const int MOD = 1e8;
int lowbit(int x) { return x & -x; }
inline ll dpow(ll a, ll b) { ll r = 1, t = a; while (b) { if (b & 1)r = (r * t) % MOD; b >>= 1; t = (t * t) % MOD; }return r; }
inline ll fpow(ll a, ll b) { ll r = 1, t = a; while (b) { if (b & 1)r = (r * t); b >>= 1; t = (t * t); }return r; }
ll n,a[maxn],f,dp[maxn][maxn];
int main()
{
    cin>>n>>f;

    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i]=a[i]%f;
    }
    for(int i=1;i<=n;i++)
    dp[i][a[i]]=1;

    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<f;j++)
        {
            dp[i][j]=dp[i][j]+dp[i-1][j]+dp[i-1][(j-a[i]+f)%f];
            dp[i][j]%=MOD;
        }
    }
   cout<<dp[n][0]<<endl;
    system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章