本来都不想写下去了,后来想想,还是写写吧!以后回过头来看看,就可以说,哦,那些时间去做这个了!
下面步入正题。
赛码网 5.12周考
题目挺难的,反正我2道题目都没有做出来,官网上也没有贴出来答案,就只好自己去找了。
1. 暴力搜索肯定是不行的,时间复杂度很高,只好找一种数个数的方法,没有想到。
题解链接:http://krydom.com/bzoj1801/
解释的应该很详细,但是我有一点疑问,
放2个到一个空列上 与 放一个到只有一个的列上,另一个放到空列上, 这两种的转移方式 应该是不同的, 但是转移的时候只需要后者, 为什么?我这里没有搞明白。
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef pair<int, int> pii; 5 const int maxn = 1e5 + 10; 6 7 ll dp[110][110][110]; 8 int n, m; 9 void add(ll &x, ll y) { 10 x += y; 11 } 12 void solve() { 13 cin >> n >> m; 14 dp[0][0][0] = 1; 15 for (int i = 1; i <= n; i++) { 16 for (int j = 0; j <= m; j++) { 17 for (int k = 0; k <= m - j; k++) { 18 ll cur = dp[i - 1][j][k]; 19 add(dp[i][j][k], cur); //1 20 if(j + 1 <= m) 21 add(dp[i][j + 1][k], cur * (m - j - k));//2 22 if(j >= 1) 23 add(dp[i][j - 1][k + 1], cur * j);//3 24 //if(k + 1 <= m) 25 //add(dp[i][j][k + 1], cur * (m - j - k)); 26 if(j + 2 <= m) 27 add(dp[i][j + 2][k], cur * (m - j - k) * (m - j - k - 1) / 2);//4 28 if(k + 1 <= m) 29 add(dp[i][j][k + 1], cur * j * (m - j - k)); 30 if(j >= 2) 31 add(dp[i][j - 2][k + 2], cur * j * (j - 1) / 2); 32 } 33 } 34 } 35 ll res = 0; 36 for (int i = 0; i <= m; i++) { 37 for (int j = 0; j <= m - i; j++) 38 add(res, dp[n][i][j]); 39 } 40 cout << res << endl; 41 } 42 43 int main() { 44 freopen("test.in", "r", stdin); 45 solve(); 46 return 0; 47 }
这个题目根本没有想法,找到题解答案也看不懂,算了,放弃了。
题解链接:http://www.cnblogs.com/suishiguang/p/6041471.html
感觉这2道题目难度很高啊,一般想不出来。
时间: 2024-10-15 10:09:04