唔。。。做悲剧了QAQ 哭瞎!
250 一开始以为苹果的包和桔子的包不是同一个包。。。500 根本没思路。。950 看的晚了(早看了也写不完。。)
250pt
枚举从每包里那几个,然后找到能拿的最小的苹果数和最大的苹果树(中间那些情况都可以达到) ans += maxapple-minapple+1;
500pt
枚举哪一位开始不同(比如 r),然后dp
dp[2005][3005][2] 表示到第i个数,Aset和Bset异或相差为j,且Aset的第r位是0/1的方案数。
因为从第r位开始不同,Aset和Bset的差j,r位之前必须全为0,且第r位为1;Aset为的第r位是0的;
答案统计一下就完了。
950pt
估计又不是正解的一个YY
先把线段按照起点排序。
因为每个位置只有两个线段重叠,那么假设这两个线段是i和ii
其中i的起点在ii前面。
dp[2][j][k]
当前状态表示为已经处理到pos位置,i这个线段已经放了j个red,k个green。
2是表示滚动数组(pos和i都是另开的变量,如果开在数组里不好表示。其实应该是dp(i,pos,j,k)?,前两维转移幅度太大就滚动了)
刚进入while的时候,要保证(pos在a[i].begin和a[i].end之间,pos在a[ii].begin之前),或者说一直维护着这个
转移:
1、如果a[i].end>=a[ii].begin 那么pos应该转移到a[i].end这个位置,当前pos到a[i].end这一段可以把剩下的颜色全排列放。
随后变化:
pos->a[ii].begin (当前位置转移到ii的开始位置)
i->ii (dp数组以ii为参考,即i变成ii,原来的i全部处理完毕)
ii->ii+1; (引入新的ii)
j->0,k->0 (ii在当前pos位置还没放东西,所以j,k都是0)
2、如果a[i].end<a[ii].begin,那么pos应该转移到a[ii].begin这个位置 (这个转移是100^4,就是枚举这一段是放red和green个数。。。。所以感觉做法不科学,但是貌似这种数据出不出来←_←)
接下来pos已经在a[ii].begin位置,然后分两种情况
2.1、a[i].end<a[ii].end
2.2、a[i].end>=a[ii].end
2的转移具体怎么搞自行脑补吧233333
代码:
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <cstring> using namespace std; class WinterAndShopping { public: int getNumber(vector<int> , vector<int> , vector<int> , vector<int> ); }; struct node { int n, st, ed; int r, g, b; } a[55]; bool cmp(node a, node b) { return a.st < b.st; } long long pmod = 1000000007; long long dp[2][105][105]; int c[505][505]; void prec() { int i, j; for (i = 0; i < 505; ++i) { c[i][0] = c[i][i] = 1; for (j = 1; j < i; ++j) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % pmod; } } int WinterAndShopping::getNumber(vector<int> first, vector<int> red, vector<int> green, vector<int> blue) { prec(); int i, j, k, n, pos; int ii, jj, kk, rr; n = first.size(); for (i = 0; i < n; ++i) { a[i].n = red[i] + green[i] + blue[i]; a[i].st = first[i]; a[i].ed = first[i] + a[i].n; a[i].r = red[i]; a[i].g = green[i]; a[i].b = blue[i]; } sort(a, a + n, cmp); int pre, now; memset(dp, 0, sizeof(dp)); dp[0][0][0] = 1; pre = 0; now = 1; i = 0; ii = 1; pos = a[0].st; while (1) { if (ii == n) break; /////////////////////////1///////////////// if (a[ii].st >= a[i].ed) { for (j = 0; j <= a[i].r; ++j) { for (k = 0; k <= a[i].g; ++k) { if (dp[pre][j][k] == 0) continue; jj = a[i].r - j; kk = a[i].g - k; rr = a[i].ed - pos - jj - kk; if (jj < 0 || kk < 0 || rr < 0) continue; dp[now][0][0] += dp[pre][j][k] * c[rr + jj + kk][rr] % pmod * c[jj + kk][jj] % pmod; dp[now][0][0] %= pmod; } } pos = a[ii].st; pre = 1 - pre; now = 1 - now; memset(dp[now], 0, sizeof(dp[now])); int tt = max(i, ii) + 1; i = ii; ii = tt; continue; } ////////////////////2////////////////////////////// int nn = a[ii].st - pos; for (j = 0; j <= a[i].r; ++j) { for (k = 0; k <= a[i].g; ++k) { if (dp[pre][j][k] == 0) continue; for (jj = 0; jj <= nn && j + jj <= a[i].r; ++jj) { for (kk = 0; kk + jj <= nn && k + kk <= a[i].g; ++kk) { rr = a[ii].st - pos - jj - kk; dp[now][j + jj][k + kk] += dp[pre][j][k] * c[rr + jj + kk][rr] % pmod * c[jj + kk][jj] % pmod; dp[now][j + jj][k + kk] %= pmod; } } } } pos = a[ii].st; pre = 1 - pre; now = 1 - now; memset(dp[now], 0, sizeof(dp[now])); ////////////////////////2.1//////////////////////// if (a[i].ed < a[ii].ed) { for (j = 0; j <= a[i].r; ++j) { for (k = 0; k <= a[i].g; ++k) { if (dp[pre][j][k] == 0) continue; jj = a[i].r - j; kk = a[i].g - k; rr = a[i].ed - pos - jj - kk; if (jj < 0 || kk < 0 || rr < 0) continue; if (jj > a[ii].r) continue; if (kk > a[ii].g) continue; if (rr > a[ii].b) continue; dp[now][jj][kk] += dp[pre][j][k] * c[rr + jj + kk][rr] % pmod * c[jj + kk][jj] % pmod; dp[now][jj][kk] %= pmod; } } pos = a[i].ed; int tt = max(i, ii) + 1; i = ii; ii = tt; } else { ////////////////////////////2.2////////////////////////// for (j = 0; j <= a[i].r; ++j) { for (k = 0; k <= a[i].g; ++k) { if (dp[pre][j][k] == 0) continue; jj = a[ii].r; kk = a[ii].g; rr = a[ii].b; if (j + jj > a[i].r) continue; if (k + kk > a[i].g) continue; if (pos - a[i].st - j - k + rr > a[i].b) continue; dp[now][j + jj][k + kk] += dp[pre][j][k] * c[rr + jj + kk][rr] % pmod * c[jj + kk][jj] % pmod; dp[now][j + jj][k + kk] %= pmod; } } pos = a[ii].ed; int tt = max(i, ii) + 1; ii = tt; } pre = 1 - pre; now = 1 - now; memset(dp[now], 0, sizeof(dp[now])); } long long ans = 0; for (j = 0; j <= a[i].r; ++j) { for (k = 0; k <= a[i].g; ++k) { if (dp[pre][j][k] == 0) continue; jj = a[i].r - j; kk = a[i].g - k; rr = a[i].ed - pos - jj - kk; if (jj < 0 || kk < 0 || rr < 0) continue; ans += dp[pre][j][k] * c[rr + jj + kk][rr] % pmod * c[jj + kk][jj] % pmod; ans %= pmod; } } return ans; }