Codeforces Gym 100342D Problem D. Dinner Problem Dp+高精度

点击打开链接

题意:有n天,有k个人,安排这k个人做饭,问你有多少种安排方案,每个人至少得做一天饭

思路: dp[i][j] 表示 从k个人中选i个人做j天的饭有多少方案, dfs(i,j) 表示前i个人做j天的饭有多少方案

转移:

if(i == 0)  dp[i][j]=dfs(i,j-1)*k; // 只能选“后面”k个

dp[i][j] = dfs(i-1,j-1)*i + dfs(i,j-1)*(k-i); // 从前i个中选一个人在第j天做饭或者从i+1到k个人里选一个。

代码:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef unsigned long long ll;
  4 #define mem(a) memset(a,0,sizeof(a))
  5 #define mp(x,y) make_pair(x,y)
  6 const int maxn = 410;
  7 const int INF = 0x3f3f3f3f;
  8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
  9 inline ll read(){
 10     ll x=0,f=1;char ch=getchar();
 11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 13     return x*f;
 14 }
 15 //////////////////////////////////////////////////////////////////////////
 16 
 17 struct bign
 18 {
 19     int len, s[maxn];
 20     bign ()
 21     {
 22         memset(s, 0, sizeof(s));
 23         len = 1;
 24     }
 25     bign (int num) { *this = num; }
 26     bign (const char *num) { *this = num; }
 27     bign operator = (const int num)
 28     {
 29         char s[maxn];
 30         sprintf(s, "%d", num);
 31         *this = s;
 32         return *this;
 33     }
 34     bign operator = (const char *num)
 35     {
 36         for(int i = 0; num[i] == '0'; num++) ;  //去前导0
 37         len = strlen(num);
 38         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
 39         return *this;
 40     }
 41     bign operator + (const bign &b) const //+
 42     {
 43         bign c;
 44         c.len = 0;
 45         for(int i = 0, g = 0; g || i < max(len, b.len); i++)
 46         {
 47             int x = g;
 48             if(i < len) x += s[i];
 49             if(i < b.len) x += b.s[i];
 50             c.s[c.len++] = x % 10;
 51             g = x / 10;
 52         }
 53         return c;
 54     }
 55     bign operator += (const bign &b)
 56     {
 57         *this = *this + b;
 58         return *this;
 59     }
 60     void clean()
 61     {
 62         while(len > 1 && !s[len-1]) len--;
 63     }
 64     bign operator * (const bign &b) //*
 65     {
 66         bign c;
 67         c.len = len + b.len;
 68         for(int i = 0; i < len; i++)
 69         {
 70             for(int j = 0; j < b.len; j++)
 71             {
 72                 c.s[i+j] += s[i] * b.s[j];
 73             }
 74         }
 75         for(int i = 0; i < c.len; i++)
 76         {
 77             c.s[i+1] += c.s[i]/10;
 78             c.s[i] %= 10;
 79         }
 80         c.clean();
 81         return c;
 82     }
 83     bign operator *= (const bign &b)
 84     {
 85         *this = *this * b;
 86         return *this;
 87     }
 88     bign operator - (const bign &b)
 89     {
 90         bign c;
 91         c.len = 0;
 92         for(int i = 0, g = 0; i < len; i++)
 93         {
 94             int x = s[i] - g;
 95             if(i < b.len) x -= b.s[i];
 96             if(x >= 0) g = 0;
 97             else
 98             {
 99                 g = 1;
100                 x += 10;
101             }
102             c.s[c.len++] = x;
103         }
104         c.clean();
105         return c;
106     }
107     bign operator -= (const bign &b)
108     {
109         *this = *this - b;
110         return *this;
111     }
112     bign operator / (const bign &b)
113     {
114         bign c, f = 0;
115         for(int i = len-1; i >= 0; i--)
116         {
117             f = f*10;
118             f.s[0] = s[i];
119             while(f >= b)
120             {
121                 f -= b;
122                 c.s[i]++;
123             }
124         }
125         c.len = len;
126         c.clean();
127         return c;
128     }
129     bign operator /= (const bign &b)
130     {
131         *this  = *this / b;
132         return *this;
133     }
134     bign operator % (const bign &b)
135     {
136         bign r = *this / b;
137         r = *this - r*b;
138         return r;
139     }
140     bign operator %= (const bign &b)
141     {
142         *this = *this % b;
143         return *this;
144     }
145     bool operator < (const bign &b)
146     {
147         if(len != b.len) return len < b.len;
148         for(int i = len-1; i >= 0; i--)
149         {
150             if(s[i] != b.s[i]) return s[i] < b.s[i];
151         }
152         return false;
153     }
154     bool operator > (const bign &b)
155     {
156         if(len != b.len) return len > b.len;
157         for(int i = len-1; i >= 0; i--)
158         {
159             if(s[i] != b.s[i]) return s[i] > b.s[i];
160         }
161         return false;
162     }
163     bool operator == (const bign &b)
164     {
165         return !(*this > b) && !(*this < b);
166     }
167     bool operator != (const bign &b)
168     {
169         return !(*this == b);
170     }
171     bool operator <= (const bign &b)
172     {
173         return *this < b || *this == b;
174     }
175     bool operator >= (const bign &b)
176     {
177         return *this > b || *this == b;
178     }
179     string str() const
180     {
181         string res = "";
182         for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;
183         return res;
184     }
185 };
186 
187 istream& operator >> (istream &in, bign &x)
188 {
189     string s;
190     in >> s;
191     x = s.c_str();
192     return in;
193 }
194 
195 ostream& operator << (ostream &out, const bign &x)
196 {
197     out << x.str();
198     return out;
199 }
200 
201 
202 bign dp[105][105];
203 int k, n;
204 
205 bign dfs(int i,int j){
206     if(dp[i][j]!=-1) return dp[i][j];
207     if(i > j) return dp[i][j]=0;
208     if(i==0 && j==0) return dp[i][j]=1;
209     if(i == 0) return dp[i][j]=dfs(i,j-1)*k;
210     return dp[i][j] = dfs(i-1,j-1)*i + dfs(i,j-1)*(k-i); // 从前i个中选一个人在第j天做饭或者从i+1到k个人里选一个。
211 }
212 
213 int main(){
214     freopen("dinner.in","r",stdin);
215     freopen("dinner.out","w",stdout);
216     //k=read(),n=read();
217     cin >> k >> n;
218     // memset(dp,-1,sizeof(dp));
219     for(int i = 0 ; i <= 100 ; ++ i)
220         for(int j = 0 ; j <= 100 ; ++ j)
221             dp[i][j] = -1;
222     cout << dfs(k,n) << endl;
223 
224     return 0;
225 }
226 
227 //http://codeforces.com/gym/100342/attachments
原文地址:https://www.cnblogs.com/yxg123123/p/6827713.html