HDU
来源:互联网 发布:nike手机抢购软件 编辑:程序博客网 时间:2024/06/04 23:30
题目大意:
给你 n 个数(1000),每个数 0<=a[ i ]<=1000,对于每个数,它有一个 b[i] 与它对应,b[ i ] 有三种值:D、L、N,分别表示 a[ i ] 只能取负,只能取正,既能取负又能取正。现在给你一个整数 k ,问你是否可以从 a 中选取若干个,使得它们的和正好等于 k 。并且告诉你 a 数组的一个限制:每一个 a[i] 都小于等于之前所有 a 的选取组合的最大值,且大于等于最小值。并且要求:a[1]=1;b[1]=N;
分析:
猜想:
对于给你的一串数 a[1]~a[i] 假设它们能组成的最大值为 max ,最小值为 min ,那么,对于区间 [ min , max ] 中的任意一个数 t ,我都有 a 中的一种选取方式使得这些数之和等于 t 。
下面我选择第一数学归纳法证明:
首先,对于i等于1,猜想显然成立;其次,假设对于某一整数 i ,猜想成立。那么对于 i+1 ,因为 a[ i ] 小于等于之前所有数能取得的最大和 max ,并且大于等于之前所有数能取到的最小和 min 。那么显然 a[ i ] 就落到了区间 [ min , max ] 里面,那么区间 [ a[ i ] , a[ i ]+max ] 之间的每一个数也都可以通过 [ 0 , max ] 之间的每一个组合加上 a[ i ] 得到(只是对于 b[ i ]=L 的情况来说)。其他两种 b 的取值同理。所以 i+1 猜想同样成立。证毕~
代码:
#include<bits/stdc++.h>using namespace std;int t,n,k,a[1050],maxx,minx;char c;int main(){ scanf("%d",&t); while(t--) { maxx=0;minx=0; scanf("%d%d",&n,&k); //cout<<n<<k<<endl; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } //cout<<n<<k; for(int i=1;i<=n;i++) { // while(1) scanf("%c",&c); while(c==' ' || c=='\n')scanf("%c",&c); if(c=='D')minx-=a[i]; else if(c=='L')maxx+=a[i]; else { maxx+=a[i]; minx-=a[i]; } } if(k>=minx&&k<=maxx)cout<<"yes"<<endl; else cout<<"no"<<endl; }}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- POJ2749 Building roads【2-SAT】
- HDU 1179 Ollivanders: Makers of Fine Wands since 382 BC.(二分图匹配+匈牙利算法)
- hdu6127Hard challenge(极角排序)
- OSG 事件处理机制 类图
- java集合2
- HDU
- Velocity快速入门教程-脚本语法详解(转)
- mysql 区分大小写 mysql安装目录 数据文件目录
- CSS备忘录
- jquery 复制元素,并修改属性,追加到另一个元素后面
- 关于android studio进行NDK编译生成.so文件
- matplotlib模块数据可视化-图片处理
- 字符串连接join( )
- 很多人想知道的:测试LDPC的方法