Codeforces Round #213 (Div. 1)
2013-11-20 21:21
190 查看
A:
题意:问有多少个子矩阵的和等于a
思路:观察一下,矩阵其实很特殊。可以提取出每行的系数。
a1*(a1,a2,..,an)
a2*(a1,a2,..,an)
.
.
.
an*(a1,a2,..,an)
用sum[i]表示数列a的前i项和。
那么任意一个子矩阵和可以表示为(sum[col1]-sum[col0])*(sum[row1]-sum[row0]) (col0<y<=col1,row0<x<=row1)
然后n^2枚举统计就好了,注意一些细节,具体看代码。
code:
B:
题意:市场上有n个物品,一开始你手上没物品。你可以用你手中的若干物品来换市场上的若干物品,条件是价值和相差不超过d。可以空手换,只要不超过d。求最大价值。
思路:一开始考虑要表示出用哪些换哪些,然后就不会做了。然后宁神告诉我,本质和拥有哪些物品毫无关系。只要物品能组成价值总和为x和y,且y-x<=d。那么一定能从x换到y。明白这点后就是dp[i]=min{dp[j]+1} ,i表示价值。用单调队列优化后复杂度O(sum{c[i]})。
code:
题意:问有多少个子矩阵的和等于a
思路:观察一下,矩阵其实很特殊。可以提取出每行的系数。
a1*(a1,a2,..,an)
a2*(a1,a2,..,an)
.
.
.
an*(a1,a2,..,an)
用sum[i]表示数列a的前i项和。
那么任意一个子矩阵和可以表示为(sum[col1]-sum[col0])*(sum[row1]-sum[row0]) (col0<y<=col1,row0<x<=row1)
然后n^2枚举统计就好了,注意一些细节,具体看代码。
code:
#include <algorithm> #include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <string> #include <math.h> #include <vector> #include <queue> #include <stack> #include <cmath> #include <list> #include <set> #include <map> using namespace std; #define N 100010 #define ALL(x) x.begin(),x.end() #define CLR(x,a) memset(x,a,sizeof(x)) typedef pair<int,int> PI; typedef long long ll; const int INF = 0x3fffffff; const int MOD = 7; const double EPS = 1e-7; char s ; int n,x,sum ; int vis ; int check(int y) { if(y==0){ if(x==0) return n*(n+1)/2; else return 0; } if( (x && x<y) || x%y) return 0; int k=x/y; if(k<=sum ) return vis[k]; return 0; } int main() { scanf("%d",&x); scanf("%s",s); n=strlen(s); for(int i=1;i<=n;i++) sum[i]=(s[i-1]-'0')+sum[i-1]; for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) vis[sum[j]-sum[i-1]]++; ll ans=0; for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) ans+=check(sum[j]-sum[i-1]); printf("%I64d\n", ans); return 0; }
B:
题意:市场上有n个物品,一开始你手上没物品。你可以用你手中的若干物品来换市场上的若干物品,条件是价值和相差不超过d。可以空手换,只要不超过d。求最大价值。
思路:一开始考虑要表示出用哪些换哪些,然后就不会做了。然后宁神告诉我,本质和拥有哪些物品毫无关系。只要物品能组成价值总和为x和y,且y-x<=d。那么一定能从x换到y。明白这点后就是dp[i]=min{dp[j]+1} ,i表示价值。用单调队列优化后复杂度O(sum{c[i]})。
code:
#include <algorithm> #include <iostream> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <string> #include <math.h> #include <vector> #include <queue> #include <stack> #include <cmath> #include <list> #include <set> #include <map> using namespace std; #define N 500010 #define ALL(x) x.begin(),x.end() #define CLR(x,a) memset(x,a,sizeof(x)) typedef pair<int,int> PI; typedef long long ll; const int INF = 0x3fffffff; const int MOD = 100000007; const double EPS = 1e-7; int c[64],dp ,vis ; deque<PI > L; PI ans; int main() { int n,d; scanf("%d%d",&n,&d); vis[0]=1; for(int i=0;i<n;i++){ scanf("%d",c+i); for(int j=N-c[i]-1;j>=0;j--) if(vis[j]) vis[j+c[i]]=1; } ans.first=0; ans.second=0; L.push_back(ans); for(int i=1;i<N;i++){ if(!vis[i]) continue; while(!L.empty() && i-L.front().first>d) L.pop_front(); if(!L.empty()){ dp[i]=L.front().second+1; ans.first=i; ans.second=dp[i]; while(!L.empty() && L.back().second>=dp[i]) L.pop_back(); L.push_back(ans); } } printf("%d %d\n",ans.first,ans.second); return 0; }
相关文章推荐
- FZU 2020 组合 Lucas的应用
- WinForm各种关闭
- Servlet3.0引入的新特性
- linux segmentation fault记录
- 在ArcGIS中计算震中到周边城市的距离,并连线标注
- iOS7滑动返回
- perl学习过程
- openSUSE v13.1
- linux segmentation fault记录
- 最大价值
- SQLite
- 业务逻辑层的设计(五)——事务脚本模式介绍
- js显示时间
- Java Hour 46 SLF4J
- 注册——登录实战演习 (使用java web应用的三层架构实现)
- 从最大似然到EM算法浅解
- c++学习之--排序4-直接选择排序
- 【OpenCV】数字图像灰度直方图
- JAVA多线程学习1
- iOS6下实现滑动返回