SRM 601 DIV1
A
枚举x , 然后对于确定的x , 最后总的apple数对应了唯一的orange数,因此问题转化为求apple的取值范围;
apple的取值范围: max为每个bag取最多的apple , min为每个bag取最小的apple , 容易证明[min,max]是连续的.
using namespace std; class WinterAndPresents {
public:
long long getNumber(vector <int>, vector <int>);
};
struct node {
int a,o;
};vector<node> f;
bool cmp(node x,node y) {
if (x.a==y.a) return x.o<y.o;
return x.a<y.a;
}
long long WinterAndPresents::getNumber(vector <int> apple, vector <int> orange) {
long long ans = ;
int x = -,n = apple.size();
for (int i= ; i<n ; i++ ) {
if (x==- || x>apple[i]+orange[i]) x=apple[i]+orange[i];
f.push_back((node){apple[i],orange[i]});
}
for (int i= ; i<=x ; i++ ) {
long long big = , sml = ;
for (int j= ; j<n ; j++ ) {
if (f[j].a>=i) big += i;
else big += f[j].a; if (f[j].o>=i) sml += ;
else sml += i-f[j].o;
}
ans += big-sml+;
}
return ans;
}
B
关键在于优化dp状态.
朴素的dp是: dp[i][mask1][mask2] 在考虑第i个数时 集合1的状态为mask1 , 集合2的状态为mask2.
为了优化掉一维,应该考虑把状态设计成 dp[i][mask1^mask2] , 然后为了识别大小再用1维记录最高非0位属于哪个集合,
再换个角度来看,可以枚举最后最高非0位在位置p , 然后用dp[i][mask1^mask2][0/1]表示:
选择了i个 ; 集合1,2的异或值异或为mask1^mask2 ; mask1在p位置是0/1
就把原来的 O(maxn*mask1*mask2) 复杂度优化为O(maxn*mask1*2*log(maxn))
最后,在实现的时候可以把 (mask1^mask2) 右移p位 , 因为最高非零位之后的都无关紧要, 此时的状态数变更小了,用dfs实现可以更快.
#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;
#define mod 1000000007
class WinterAndSnowmen {
public:
int getNumber(int, int);
};
int dp[][<<][],p,n,m;
int dfs(int t,int sum,int b) {
//printf("t:%d sum:%d b:%d\n",t,sum,b);
if (t==) {
// printf("p:%d sum:%d b:%d\n",p,sum,b);
if ( sum== && b== ) return ;
else return ;
}
if (dp[t][sum][b]!=-) return dp[t][sum][b];
else {
long long res = ;
if (t<=n) {
res += dfs( t- , sum^(t>>p) , b^((t>>p)&) );
}
if (t<=m) {
res += dfs(t- , sum^(t>>p) , b );
}
res += dfs( t- , sum , b );
res %= mod;
return dp[t][sum][b]=(int)res;
}
}
int WinterAndSnowmen::getNumber(int N, int M) {
int res = ;
n = N , m = M;
for (int i= ; i< ; i++ ) {
memset(dp,-,sizeof(dp));
p = i;
res += dfs(max(N,M),,);
res %= mod;
// printf("i:%d add:%d\n",i,tmp);
}
return res;
} //Powered by [KawigiEdit] 2.0!
C
又是个需要状态优化的dp.
朴素的状态设计是: f(t , r0 , g0 , b0 , r1 , g1 , b1) , 表示第t天 , 第一个shop的销售情况和第二个shop的销售情况;
但是考虑到两个shop同时营业时 , 销售情况必须一致 , 当碰到有同时营业的情况时 , 可以直接跳到下一个结束点:
于是新的状态表示为 f(t,r0,g0,b0) ;
然后再通过各种判断,来知道如何转移;
进一步优化是去掉b0的记录, 因为每天必须售出一个ball , 知道当前天t,开始天first,已经其它销售情况就能计算出b0.
最后的状态表示为f(t,r0,g0).
using namespace std;
#define maxn 510
#define mod 1000000007
class WinterAndShopping {
public:
int getNumber(vector <int>, vector <int>, vector <int>, vector <int>);
}; struct node{
int f,r,g,b;
int end() {
return f+r+g+b;
}
};vector<node> s[maxn];
int dp[maxn][][],c[maxn][maxn]; void pretreat(vector<int> f, vector<int> r, vector<int> g, vector<int> b) {
for (int i= ; i<(int)f.size() ; i++ ) {
for (int j=f[i] ; j<f[i]+r[i]+g[i]+b[i] ; j++ ) {
s[j].push_back((node){f[i],r[i],g[i],b[i]});
}
}
for (int i= ; i<maxn ; i++ ) if (s[i].size()==) {
if (s[i][].f>s[i][].f) swap(s[i][],s[i][]);
}
for (int i= ; i<maxn ; i++ ) {
c[i][] = ;
for (int j= ; j<=i ; j++ )
c[i][j] = (c[i-][j-] + c[i-][j]) % mod;
}
} long long getfct(int r,int g,int b) {
long long res = (long long)c[r+g+b][r] * (long long )c[g+b][g] % mod;
// printf("r:%d g:%d b:%d res:%lld\n",r,g,b,res);
return res;
} long long dfs(int t,int r,int g) {
if (t==) {
if (r== && g==) return ;
else return ;
}
if (dp[t][r][g]!=-) return (long long)dp[t][r][g];
else {
long long res = ;
if (s[t].size()==) res = dfs(t+,,);
else if (s[t].size()==) {
if (t+ == s[t][].end()) res = dfs(t+,,);
else {
if (r+<=s[t][].r) res += dfs(t+,r+,g);
if (g+<=s[t][].g) res += dfs(t+,r,g+);
if (t-s[t][].f-r-g+<=s[t][].b) res += dfs(t+,r,g);
}
res %= mod;
}
else if (s[t].size()==) {
node s0 = s[t][] , s1 = s[t][];
int b = (t-s0.f-(r+g));
if (s0.end() == s1.end()) {
if (s0.r-r==s1.r && s0.g-g==s1.g && s0.b-b==s1.b) {
res = getfct(s1.r,s1.g,s1.b) * dfs(s1.end(),,) % mod;
}
} else if (s0.end() < s1.end()) {
if (s0.r-r<=s1.r && s0.g-g<=s1.g && s0.b-b<=s1.b) {
res = getfct(s0.r-r,s0.g-g,s0.b-b) * dfs(s0.end(),s0.r-r,s0.g-g) % mod;
}
} else if (s0.end() > s1.end()) {
if (s1.r<=s0.r-r && s1.g<=s0.g-g && s1.b<=s0.b-b) {
res = getfct(s1.r,s1.g,s1.b) * dfs(s1.end(),r+s1.r,g+s1.g) % mod;
}
}
}
dp[t][r][g] = (int)res;
return res;
}
} int WinterAndShopping::getNumber(vector <int> f, vector <int> r, vector <int> g, vector <int> b) {
pretreat(f,r,g,b);
memset(dp,-,sizeof(dp));
long long ans = dfs(,,);
return (int)ans;
}
SRM 601 DIV1的更多相关文章
- Topcoder SRM 601 div1题解
日常TC计划- Easy(250pts): 题目大意:有n个篮子,每个篮子有若干个苹果和橘子,先任取一个正整数x,然后从每个篮子中选出x个水果,把nx个水果放在一起,输出一共有多少种不同的组成方案.其 ...
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- 图论 SRM 674 Div1 VampireTree 250
Problem Statement You are a genealogist specializing in family trees of vampires. Vampire famil ...
- SRM 601(1-250pt,500pt)
DIV1 250pt 题意:有很多袋子,里面装有苹果和橘子(也可能没有),给出每个袋子里有多少个苹果,多少个橘子.如果每个袋子里含有水果的总数都不小于x个,则可以从每个袋子里都拿出x个水果(拿出苹果和 ...
- SRM 583 DIV1
A 裸最短路. class TravelOnMars { public: int minTimes(vector <int>, int, int); }; vector<int> ...
- SRM 590 DIV1
转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlov ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- 状态压缩DP SRM 667 Div1 OrderOfOperations 250
Problem Statement Cat Noku has just finished writing his first computer program. Noku's compute ...
随机推荐
- TsFltMgr.sys系统蓝屏的原因就在于QQ电脑管家!
同事一WindowsXP系统,正常执行,关闭后,第二天无法启动,详细症状为: (1)安全模式以及带网络功能的安全模式都能够进入: (2)正常模式,还没出现WindowXP滚动栏就開始重新启动: (3) ...
- xheditor编辑器上传截图图片抓取远程图片代码
xheditor是一款很不错的开源编辑器,用起来很方便也很强大. 分享一个xheditor直接上传截图的问题解决方法. 第一步.设置参数 localUrlTest:/^https?:\/\/[^\/] ...
- Android(java)学习笔记252:ContentProvider使用之内容观察者01
1. 内容观察者 不属于四大组件,只是内容提供者ContentProvider对应的小功能. 如果发现数据库内容变化了,就会立刻观察到. 下面是逻辑图: 当A应用中银行内部的数据发生变化的 ...
- python复制--笔记
对象引用: >>> songs = ["Bee","Core","Love"] >>> bat = so ...
- OD: DEP - Ret2Libc via VirtualProtect() & VirtualAlloc()
一,通过 VirutalProtect() 修改内存属性绕过 DEP DEP 的四种工作模式中,OptOut 和 AlwaysOn 下所有进程默认都开启 DEP 保护,这里如果一个程序自身需要从堆栈中 ...
- QQ互联OAuth2.0 .NET SDK 发布以及网站QQ登陆示例代码
OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容. QQ登录OAuth2 ...
- POJ1502
#include <iostream> #include <cstdio> #include <algorithm> #include <climits> ...
- 关于在repeater中的checkbox实行多选和全选
今天项目中用到这一块,是一个b2b商城,业务是别人给客户留言后,客户从会员中心的留言管理中查看,用checkbox实行多选和全选后进行批量审核 首先在checkbox后加个hidden,作用见代码: ...
- android获取在res文件下的图片资源
//得到该图片的id(name 是该图片的名字,"drawable" 是该图片存放的目录,getPackageName()是应用程序的包) int resID = getResou ...
- C# - openxml 操作excel - '“System.IO.Packaging.Package”在未被引用的程序集中定义'
在 CodeProject中,有位网友写的一篇基于OpenXML SDK 2.0对excel(大数据量)进行操作,其中,运行的时候,有如下错误: 类型“System.IO.Packaging.Pack ...