学校作业-Dp练习
题目
★Stringsobits01 串
考虑排好序的 N(N<=31)位二进制数.
你会发现,这很有趣.因为他们是排列好的,而且包含所有可能的长度为 N 且含有 1 的个数小于等于
L(L<=N)的数.
你的任务是输出第 I(1<=I<=长度为 N 的二进制数的个数)大的,长度为 N,且含有 1 的个数小于等
于 L 的那个二进制数.
PROGRAM NAME: kimbits
INPUT FORMAT
共一行,用空格分开的三个整数 N,L,I.
SAMPLE INPUT (file kimbits.in)
5 3 19
OUTPUT FORMAT
共一行,输出满足条件的第 I 大的二进制数.
SAMPLE OUTPUT (file kimbits.out)
10011
题解
这道题吧,我觉得就是一位一位试,如果当前填0,用组合数计算一下共有多少个数字,如果小于i的话,当前就填1,否则就填0,一直试下去就可以了。我猜它可以数位DP?没仔细想QAQ
代码
/*Author:WNJXYK*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std; #define LL long long inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
inline int remin(int a,int b){if (a<b) return a;return b;}
inline int remax(int a,int b){if (a>b) return a;return b;}
inline LL remin(LL a,LL b){if (a<b) return a;return b;}
inline LL remax(LL a,LL b){if (a>b) return a;return b;} LL n,l,m;
int Ans[40];
LL Pow[32];
inline LL getC(int n,int m){
LL Ans=1;
if (n-m>m) m=n-m;
for (int i=m+1;i<=n;i++) Ans*=i;
for (int i=2;i<=n-m;i++) Ans/=i;
return Ans;
}
inline LL getCS(int n,int m){
LL Ans=1;
for (int i=1;i<=m;i++) Ans+=getC(n,i);
return Ans;
}
int main(){
scanf("%lld%lld%lld",&n,&l,&m);
for (int i=n;i>=2;i--){
LL tmp=getCS(i-1,remin(i-1,(int)l));
if (tmp<m){
m-=tmp;
Ans[i]=1;
l-=1;
}else{
Ans[i]=0;
}
}
Ans[1]=!(m==1);
bool isOne=false;
for (int i=n;i>=1;i--){
isOne=isOne||Ans[i];
if (isOne) printf("%d",Ans[i]);
}
printf("\n");
return 0;
}
题目
★Raucous Rockers“破锣摇滚”乐队
你刚刚继承了流行的“破锣摇滚”乐队录制的尚未发表的 N(1 <= N <= 20)首歌的版权.你打算从
中精选一些歌曲,发行 M(1 <= M <= 20)张 CD.每一张 CD 最多可以容纳 T(1 <= T <= 20)分钟的音
乐,一首歌不能分装在两张 CD 中.
不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值.于是你决定根据以下标准进行选择:
歌曲必须按照创作的时间顺序在 CD 盘上出现. 选中的歌曲数目尽可能地多.
PROGRAM NAME: rockers
INPUT FORMAT
第一行: 三个整数:N, T, M.
第二行: N 个整数,分别表示每首歌的长度,按创作时间顺序排列.
SAMPLE INPUT (file rockers.in)
4 5 2
4 3 4 2
OUTPUT FORMAT
一个整数,表示可以装进 M 张 CD 盘的乐曲的最大数目.
SAMPLE OUTPUT (file rockers.out)
3
题解
这道题目我调了好长时间,我自我检讨QAQ,因为太困了【鬼信你啊!好吧,f[i][j]={a,b}表示前i个歌曲装j首,最少需要a个光碟,并且那种情况下最后一张光碟剩余b分钟之间。这样从f[i-1][j]和f[i-1][j-1]随便转移就好了!
代码
/*Author:WNJXYK*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std; #define LL long long inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
inline int remin(int a,int b){if (a<b) return a;return b;}
inline int remax(int a,int b){if (a>b) return a;return b;}
inline LL remin(LL a,LL b){if (a<b) return a;return b;}
inline LL remax(LL a,LL b){if (a>b) return a;return b;} int n,t,m;
int ti[25];
struct Node{
int index;
int left;
Node(){index=left=2147483647;}
Node(int a,int b){index=a;left=b;};
void update(Node x){
int i=x.index;
int l=x.left;
if (i<index){
index=i;
left=l;
}else if (i==index && l<left){
left=l;
}
}
void update_new(Node x,int xt){
update(Node(x.index+1,t-xt));
if (x.left-xt>=0) update(Node(x.index,x.left-xt));
}
};
Node f[25][25]; int main(){
scanf("%d%d%d",&n,&t,&m);
for (int i=1;i<=n;i++) scanf("%d",&ti[i]);
f[0][0].index=0;
f[0][0].left=t;
int min=2147483647;
for (int i=1;i<=n;i++){
for (int j=1;j<=i;j++){
f[i][j].update(f[i-1][j]);
f[i][j].update_new(f[i-1][j-1],ti[j]);
}
}
int Ans=0;
for (int i=1;i<=n;i++)if (f[n][i].index<=m) Ans=i;
printf("%d\n",Ans);
return 0;
}
题目
★Canada Tour 周游加拿大
你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票.旅行在这家航空公司开放的最西
边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开
始的城市.每个城市只能访问一次,除了旅行开始的城市之外,这个城市必定要被访问两次(在旅行
的开始和结束).你不允许使用其他公司的航线或者用其他的交通工具.
给出这个航空公司开放的城市的列表,和两两城市之间的直达航线列表.找出能够访问尽可能多的
城市的路线,这条路线必须满足上述条件,也就是从列表中的第一个城市开始旅行,访问到列表中最
后一个城市之后再返回第一个城市.
PROGRAM NAME: tour
INPUT FORMAT
Line 1: 航空公司开放的城市数 N 和将要列出的直达航线的数量 V.N 是一个不大于 100 的
正整数.V 是任意的正整数.
Lines 2..N+1: 每行包括一个航空公司开放的城市名称.城市名称按照自西向东排列.不会出
现两个城市在同一条经线上的情况.每个城市的名称都是一个字符串,最多 15 字节,由拉丁字母表
上的字母组成;城市名称中没有空格.
Lines N+2..N+2+V-1: 每行包括两个城市名称(由上面列表中的城市名称组成),用一个空格分开.
这样就表示两个城市之间的直达双程航线.
SAMPLE INPUT (file tour.in)
8 9
Vancouver
Yellowknife
Edmonton
Calgary
Winnipeg
Toronto
Montreal
Halifax
Vancouver Edmonton
Vancouver Calgary
Calgary Winnipeg
Winnipeg Toronto
Toronto Halifax
Montreal Halifax
Edmonton Montreal
Edmonton Yellowknife
Edmonton Calgary
OUTPUT FORMAT
Line 1: 按照最佳路线访问的不同城市的数量 M.如果无法找到路线,输出 1.
SAMPLE OUTPUT (file tour.out)
7
也就是: Vancouver, Edmonton, Montreal, Halifax, Toronto, Winnipeg, Calgary, 和 Vancouver
(回到开始城市,但是不算在不同城市之内).
题解
这里我们反向返回的边,就变成了求两个不同路径。我们使用f[i][j]表示两个人一个到第i个城市,一个到第j个城市的经过城市数量。我们在转移的时候时刻保证i<j这样我们有一条k->j的边一定可以保证没有在f[i][k]中走过,因为f[i][k]还没有考虑j这个点。然后我们有对称性可知,f[i][j]=f[j][i]就这样愉快的一直推,最后找到最大的f[i][n]就可以了!
代码
/*Author:WNJXYK*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std; #define LL long long inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;}
inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;}
inline int remin(int a,int b){if (a<b) return a;return b;}
inline int remax(int a,int b){if (a>b) return a;return b;}
inline LL remin(LL a,LL b){if (a<b) return a;return b;}
inline LL remax(LL a,LL b){if (a>b) return a;return b;} map<string,int> city;
bool g[105][105];
int f[105][105];
int n,m;
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
string tmp;
cin>>tmp;
city[tmp]=i;
}
for (int i=1;i<=m;i++){
string tmp1,tmp2;
cin>>tmp1>>tmp2;
g[city[tmp1]][city[tmp2]]=g[city[tmp2]][city[tmp1]]=true;
}
f[1][1]=1;
for (int i=1;i<=n;i++){
for (int j=i+1;j<=n;j++){
for (int k=1;k<j;k++){
if (g[k][j] && f[i][k]>0 && f[i][k]+1>f[i][j]) f[i][j]=f[j][i]=f[i][k]+1;
}
}
}
int Ans=1;
for (int i=1;i<=n;i++){
if (g[i][n] && f[i][n]>Ans) Ans=f[i][n];
}
printf("%d\n",Ans);
return 0;
}
P.S.今天的作业做得略慢啊!BZOJ还剩48次提交,用完它!
学校作业-Dp练习的更多相关文章
- 学校作业-Usaco DP水题
好吧,因为USACO挂掉了,所以我写的所有代码都不保证正确性[好的,这么简单的题,再不写对,你就可以滚粗了! 第一题是USACO 2.2.2 ★Subset Sums 集合 对于从 1 到 N 的连 ...
- 【BZOJ3379】[Usaco2004 Open]Turning in Homework 交作业 DP
[BZOJ3379][Usaco2004 Open]Turning in Homework 交作业 Description 贝茜有C(1≤C≤1000)门科目的作业要上交,之后她要去坐巴士和奶 ...
- BZOJ3791:作业(DP)
Description 众所周知,白神是具有神奇的能力的. 比如说,他对数学作业说一声“数”,数学作业就会出于畏惧而自己完成:对语文作业说一声“语”,语文作业就会出于畏惧而自己完成. 今天,语文老师和 ...
- 【BZOJ3791】作业 DP
[BZOJ3791]作业 Description 众所周知,白神是具有神奇的能力的.比如说,他对数学作业说一声“数”,数学作业就会出于畏惧而自己完成:对语文作业说一声“语”,语文作业就会出于畏惧而自己 ...
- hdu 1074(状态压缩dp+记录路径)
题意:给了n个家庭作业,然后给了每个家庭作业的完成期限和花费的实践,如果完成时间超过了期限,那么就要扣除分数,然后让你找出一个最优方案使扣除的分数最少,当存在多种方案时,输出字典序最小的那种,因为题意 ...
- [原博客] HEOI2014 行记
HEOI: 河北省信息学竞赛省队选拔赛 HEOI数据标程下载 百度盘 http://pan.baidu.com/s/1qWx7YAo 又到了一年一度的HEOI呢. 我果然还是太弱了呢. Day0 报到 ...
- 开园第一篇 - 论移动开发环境 IOS与Android的差异
首先,在真正写技术之前做个自我简介.本人08年开始学c语言 一年后,转vc++.开始接触MFC MFC做了两年.转眼11年了我考上了一个不知名的大专.搞C++发现没有市场了因为当时酷狗腾讯的软件已经日 ...
- 关于qt学习的一点小记录(1)
今日为了应付学校作业要求 决定现学qt来制作界面 毕竟c++不像在这方面c#可以那么方便 qt主要依靠信号.槽来实现类似winform中的消息 鉴于要尽快做完,故而没有细看qt 只是大概了解了下界面的 ...
- Microsoft Power BI 学习笔记
Power Bi 学习笔记 一 Power BI 是微软发布的一系列的软件服务.应用和连接器,这些软件服务.应用和连接器协同工作,将不相关的数据源转化为合乎逻辑.视觉上逼真的交互式见解. ...
随机推荐
- git将本地项目添加到github远程仓库
1.首先准备好你的github 账号密码,注册就不说了.. 2.由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以要在本地生成一个私钥和一个密钥 命令: $ ssh-keygen ...
- js执行环境相关
Js执行过程 如果一个文档中存在多个代码段 步骤一:读入第一个代码段(js引擎并非一行一行执行,而是一段一段分析执行) 步骤二:做词法分析和语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤 ...
- Ubuntu_16.04 配置 Apache Rwrite URL 重写
Ubuntu Apache配置Rwrite URL重写 0. apache目录
- iOS 时钟动画
在iOS开发中,定时器NSTimer并不能够准确的出发,通常使用NSTimer只能控制不需要精确处理的操作,而CADisplayLink就是在每次屏幕刷新时,通知系统.CADisplayLink最大的 ...
- JavaSE_ 集合框架 总目录(15~18)
JavaSE学习总结第15天_集合框架1 15.01 对象数组的概述和使用15.02 对象数组的内存图解15.03 集合的由来及与数组的区别15.04 集合的继承体系图解15.05 Collectio ...
- C# 读书笔记之继承与多态
1.1继承与多态的基本概念 1.1.1 继承和多态 继承是面向对象程序设计的主要特征之一,允许重用现有类(基类,亦称超类.父类)去创建新类(子类,亦称派生类)的过程.子类将获取基类的所有非私有数据和行 ...
- MultiView空间例子
CSS代码: body { font-size:11pt; font-family:宋体; } .mainTitle { font-size:11pt; font-weight:bold; font- ...
- BZOJ 1874 取石子游戏 (NIM游戏)
题解:简单的NIM游戏,直接计算SG函数,至于找先手策略则按字典序异或掉,去除石子后再异或判断,若可行则直接输出. #include <cstdio> const int N=1005; ...
- 运行于64操作系统上的C#客户端通过WCF访问Oracle数据库不兼容问题
运行平台: Windows 7 64位操作系统 运行环境: IIS 7 编程语言:C# 数据库: 32位的Oracle 10g 运行原因:64位操作系统C#客户端程序通过WCF访问ORACLE数据库 ...
- Java_java多线程下载-断点下载-超详细
基本原理:利用URLConnection获取要下载文件的长度.头部等相关信息,并设置响应的头部信息.并且通过URLConnection获取输入流,将文件分成指定的块,每一块单独开辟一个线程完成数据的读 ...