1.第K小数 (number.cpp/c/pas)

【问题描述】

有两个正整数数列,元素个数分别为N和M。从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少。

【输入格式】

输入文件名为number.in。

输入文件包含三行。

第一行为三个正整数N,M和K。

第二行为N个正整数,表示第一个数列。

第三行为M个正整数,表述第二个数列。

【输出格式】

输出文件名为number.out。

输出文件包含一行,一个正整数表示第K小数。

【输入输出样例1】

number.in

2 3 4

1 2

2 1 3

number.out  

3

【输入输出样例2】

number.in

5 5 18

7 2 3 5 8

3 1 3 2 5

number.out  

16

【数据规模与约定】

二分

/*
考试的时候也想到了二分 但是想的是二分套二分 有整数除整数 精度有问题
自己的思路是 二分的每一个X 枚举A序列 算出B中的元素 二分找到位置 这之前的都ok
但是精度有问题 有问题.... O(logMX*n*logm)
正解就很好地避免了这个问题
差不多的思路 二分 然后循环A序列
精华之处在于 每次检验B的时候是沿着上一个Ai确定的位置
因为排好序之后 就很好的具有了这个性质 复杂度 O(logMX*(n+m))
*/
#include<cstdio>
#include<algorithm>
#define maxn 200010
#define ll long long
using namespace std;
ll n,m,k,a[maxn],b[maxn],c[maxn],ans,num;
ll init(){
ll x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
ll Judge(ll x){
ll cnt=,p=m;
for(int i=;i<=n;i++){
while(b[p]*a[i]>x&&p)p--;
cnt+=p;
}
return cnt;
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
n=init();m=init();k=init();
for(int i=;i<=n;i++)a[i]=init();
for(int i=;i<=m;i++)b[i]=init();
sort(a+,a++n);sort(b+,b++m);
ll l=,r=a[n]*b[m];
while(l<=r){
ll mid=(l+r)/;
if(Judge(mid)>=k){
r=mid-;ans=mid;
}
else l=mid+;
}
printf("%I64d\n",ans);
return ;
}

2. dwarf tower (dwarf.cpp/c/pas)

【问题描述】

Vasya在玩一个叫做"Dwarf Tower"的游戏,这个游戏中有n个不同的物品, 它们的编号为1到n。现在Vasya想得到编号为1的物品。 获得一个物品有两种方式:

1. 直接购买该物品,第i件物品花费的钱为ci

2. 用两件其他物品合成所需的物品,一共有m种合成方式。

请帮助Vasya用最少的钱获得编号为1的物品。

【输入格式】

第一行有两个整数n,m(1<=n<=10000,0<=m<=100000),分别表示有n种物品以 及m种合成方式。

接下来一行有n个整数,第i个整数ci表示第i个物品的购买价格,其中 0<=ci<=10^9。

接下来m行,每行3个整数ai,xi,yi,表示用物品xi和yi可以合成物品ai,其 中(1<=ai,xi,yi<=n; ai<>xi, xi<>yi, yi<>ai)

【输出格式】
一行,一个整数表示获取物品 1 的最少花费。
输入样例:
5 3           
5 0 1 2 5
5 2 3
4 2 3
1 4 5

 输出样例:

2

【数据规模与约定】

60%的数据, n<=100
100%的数据, n<=10000, m<=100000

记忆化75爆栈

/*暴力+记忆化+乱搞 妥妥的爆栈了 其实这样做由bug...*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define inf 1e8
#define maxn 100010
#define ll long long
using namespace std;
ll n,m,num,head[maxn],c[maxn],f[maxn],vis[maxn];
struct node{
ll u,v1,v2,pre;
}e[maxn];
ll init(){
ll x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
ll Min(ll x,ll y){
return x<y?x:y;
}
void Add(int from,int to1,int to2){
num++;e[num].u=from;
e[num].v1=to1;
e[num].v2=to2;
e[num].pre=head[from];
head[from]=num;
}
ll Dfs(ll now){
if(f[now]!=-)return f[now];
if(vis[now]>)return c[now];
ll sum=c[now];vis[now]++;
for(int i=head[now];i;i=e[i].pre){
int v1=e[i].v1,v2=e[i].v2;
sum=Min(sum,Dfs(v1)+Dfs(v2));
}
return f[now]=sum;
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
n=init();m=init();ll a,x,y;
memset(f,-,sizeof(f));
for(int i=;i<=n;i++)c[i]=init();
for(int i=;i<=m;i++){
a=init();x=init();
y=init();Add(a,x,y);
}
cout<<Dfs()<<endl;
return ;
}

建图+最短路

#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int n,m,num,head[maxn],c[maxn],dis[maxn],f[maxn];
int q[maxn],hea,tai;
struct node{
int v,t,pre;
}e[maxn*];
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Add(int from,int to,int dis){
num++;e[num].v=to;
e[num].t=dis;
e[num].pre=head[from];
head[from]=num;
}
int SPFA(){
for(int i=;i<=n;i++){
dis[i]=c[i];q[++tai]=i;f[i]=;
}
while(hea<=tai){
int k=q[++hea];f[k]=;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(dis[v]>dis[k]+dis[e[i].t]){
dis[v]=dis[k]+dis[e[i].t];
if(f[v]==){
f[v]=;q[++tai]=v;
}
}
}
}
return dis[];
}
int main(){
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
n=init();m=init();
for(int i=;i<=n;i++)
c[i]=init();
int x,y,z;
for(int i=;i<=m;i++){
x=init();y=init();z=init();
Add(z,x,y);Add(y,x,z);
}
printf("%d\n",SPFA());
fclose(stdin);fclose(stdout);
return ;
}

3. abcd (abcd.cpp/c/pas)

【问题描述】

有4个长度为N的数组a,b,c,d。现在需要你选择N个数构成数组e,数组e满足 a[i]≤e[i]≤b[i]以及

并且使得最大。

【输入格式】

输入文件名为abcd.in。

输入文件共 N+1 行。

第 1 行包含1个正整数N。

第 i+1 行包含4个整数a[i],b[i],c[i],d[i]。

【输出格式】

输出文件名为abcd.out。

输出共1行,包含1个整数,表示所给出公式的最大值。

输入数据保证一定有 解。

【输入输出样例1】

abcd.in

5

- 1 1 2 5

-2 2 1 2

0 1 1 3

-2 -1 3 10

-2 2 3 9

 

abcd.out  

2

【输入输出样例2】

abcd.in

10

1 10 1 7

-10 10 2 0

-10 10 2 2

-10 10 2 0

1 10 1 0

-10 10 2 0

10 10 2 0

1 10 1 0

-10 10 2 0

1 10 1 0

abcd.out  

90

【输入输出样例3】

abcd.in

10

1 10 1 0

-10 10 2 2

-10 10 2 2

-10 10 2 2

1 10 1 0

-10 10 2 2

-10 10 2 2

1 10 1 0

-10 10 2 2

1 10 1 0 

 

abcd.out

-4

【数据规模与约定】

对于 20%的数据, N≤10, -2≤a[i]<b[i]≤2;

对于 60%的数据, N≤50, -20≤a[i]<b[i]≤20;

对于 100%的数据, N≤200, -25≤a[i]<b[i]≤25, 1≤c[i]≤20, 0≤d[i] ≤10000

暴力20

/*暴力+剪枝+卡时 剪wa了...wa了...*/
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
#define inf 1e9
#define maxn 210
using namespace std;
int n,a[maxn],b[maxn],c[maxn],d[maxn],ans=-inf;
int mb[maxn],mc[maxn],md[maxn],na[maxn],nc[maxn];
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
void Dfs(int now,int C,int D){
if(clock()>){
printf("%d\n",ans);exit();
}
if(C+mb[now]*mc[now]*(n-now+)<)return;
if(C+na[now]*nc[now]*(n-now+)>)return;//这句剪枝有毒....
if(D+mb[now]*md[now]*(n-now+)<=ans)return;
if(now==n+){
if(C==&&D>ans)ans=D;return;
}
for(int i=a[now];i<=b[now];i++){
Dfs(now+,C+c[now]*i,D+d[now]*i);
}
}
int main()
{
freopen("abcd.in","r",stdin);
freopen("abcd.out","w",stdout);
n=init();
for(int i=;i<=n;i++){
a[i]=init();b[i]=init();
c[i]=init();d[i]=init();
}
mb[n]=b[n];
for(int i=n-;i>=;i--)
mb[i]=max(b[i],mb[i+]);
mc[n]=c[n];
for(int i=n-;i>=;i--)
mc[i]=max(c[i],mc[i+]);
md[n]=d[n];
for(int i=n-;i>=;i--)
md[i]=max(d[i],md[i+]);
na[n]=a[n];
for(int i=n-;i>=;i--)
na[i]=min(a[i],na[i+]);
nc[n]=c[n];
for(int i=n-;i>=;i--)
nc[i]=min(c[i],nc[i+]);
Dfs(,,);printf("%d\n",ans);
return ;
}

正解多重背包 Orz 真的很机智 很好地题

#include<cstdio>
#include<cstring>
#define maxn 100010
using namespace std;
int n,m,f[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
int w[maxn],v[maxn],num,ans;
int init(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=x*+s-'';s=getchar();}
return x*f;
}
int max(int x,int y){
return x>y?x:y;
}
void Ready(int W,int V,int C){
for(int i=;i<=C;i*=){
C-=i;w[++num]=W*i;v[num]=V*i;
}
if(C)w[++num]=W*C,v[num]=V*C;
}
int main()
{
//freopen("abcd.in", "r", stdin);
//freopen("abcd.out", "w", stdout);
memset(f,-/,sizeof(f));
n=init();f[]=;
for(int i=;i<=n;i++){
a[i]=init();b[i]=init();
c[i]=init();d[i]=init();
b[i]-=a[i];m-=c[i]*a[i];
ans+=a[i]*d[i];
}
for(int i=;i<=n;i++)
Ready(c[i],d[i],b[i]);
for(int i=;i<=num;i++)
for(int j=m;j>=w[i];j--)
f[j]=max(f[j],f[j-w[i]]+v[i]);
printf("%d\n",ans+f[m]);
return ;
}

最新文章

  1. 【树莓派】树莓派使用4G模块上网
  2. npm 安装 ionic cordova
  3. linux 远程桌面连接
  4. HTML5预学习 长期更新
  5. Mastering Web Application Development with AngularJS 读书笔记(三)
  6. freemarker springmvc配置异常
  7. yii2多语言
  8. React Native学习笔记-1:JSC profiler is not supported.
  9. 【总结】java命令解析以及编译器,虚拟机如何定位类
  10. WPF 在画布中布局N行N列的实现方法
  11. Oracle RAC LoadBalance
  12. dict两种遍历方法
  13. .net mvc mssql easyui treegrid 及时 编辑 ,支持拖拽
  14. SublimeLinter 3中使用jshint
  15. Linux防火墙配置—SNAT2
  16. Smrty模版总结(转)
  17. redis中使用 check-and-set 操作实现乐观锁
  18. Mysql(三)-2:数据类型
  19. iOS开发只简单动画实现
  20. python添加post请求

热门文章

  1. 四种必须知道的Android屏幕自适应解决方案
  2. NavigationDrawer+Fragment实现侧滑菜单效果
  3. 动态规划(计数DP):JLOI 2016 成绩比较
  4. T-SQL查询进阶--详解公用表表达式(CTE)
  5. HDU-2952 Counting Sheep (DFS)
  6. Linux内核学习笔记2——Linux内核源码结构
  7. uploadify上传图片(限制最多五张)
  8. 我的第一篇Markdown博客
  9. Linux安装Team Service Agent
  10. JAVA基础英语单词表(中)