SCOI 2009
作者:互联网
BZOJ 1024 生日快乐 (DFS)
Description
windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕。现在包括windy
,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋糕。windy主刀,每一切只能平行于一块蛋糕
的一边(任意一边),并且必须把这块蛋糕切成两块。这样,要切成 N 块蛋糕,windy必须切 N-1 次。为了使得
每块蛋糕看起来漂亮,我们要求 N块蛋糕的长边与短边的比值的最大值最小。你能帮助windy求出这个比值么?
Input
包含三个整数,X Y N。1 <= X,Y <= 10000 ; 1 <= N <= 10
Output
包含一个浮点数,保留6位小数。
Sample Input
5 5 5
Sample Output
1.800000
一道水题
dfs搜索
没有难度?
/**************************************************************
Problem: 1024
User: wiiind
Language: C++
Result: Accepted
Time:224 ms
Memory:1288 kb
****************************************************************/
#include<cstdio>
#include<iostream>
using namespace std;
int x,y,n;
double DFS(double x,double y,int d){
if(d == 1) return max(x,y)/min(x,y);
double res=23333333.33;
for(int i=1;i<d;i++) res=min(res,max(DFS(x,y*i/d,i),DFS(x,y*(d-i)/d,d-i)));
for(int i=1;i<d;i++) res=min(res,max(DFS(x*i/d,y,i),DFS(x*(d-i)/d,y,d-i)));
return res;
}
int main(){
cin>>x>>y>>n;
printf("%.6lf",DFS(x,y,n));
return 0;
}
BZOJ 1025 游戏(线性筛+线性DP)
Description
windy学会了一种游戏。对于1到N这N个数字,都有唯一且不同的1到N的数字与之对应。最开始windy把数字按
顺序1,2,3,……,N写一排在纸上。然后再在这一排下面写上它们对应的数字。然后又在新的一排下面写上它们
对应的数字。如此反复,直到序列再次变为1,2,3,……,N。
如: 1 2 3 4 5 6 对应的关系为 1->2 2->3 3->1 4->5 5->4 6->6
windy的操作如下
1 2 3 4 5 6
2 3 1 5 4 6
3 1 2 4 5 6
1 2 3 5 4 6
2 3 1 4 5 6
3 1 2 5 4 6
1 2 3 4 5 6
这时,我们就有若干排1到N的排列,上例中有7排。现在windy想知道,对于所有可能的对应关系,有多少种可
能的排数。
Input
包含一个整数N,1 <= N <= 1000
Output
包含一个整数,可能的排数。
Sample Input
【输入样例一】
3
【输入样例二】
10
Sample Output
【输出样例一】
3
【输出样例二】
16
这道题有一定难度
显然dfs是不行的
思路:
考虑每个关系对答案的影响
可以模拟一下这个过程:
1.手动选取n种对应方式
2.将每一个数看做一个节点,将每一种对应方式看做一条有向边,例如:3可变成5,则从3节点连一条有向边到5节点
3.可以发现必定存在环,每个环的大小可以记录下来,则该种对应方式的集合的排数为这些环的大小的lcm
那么答案则变为有一个长度为n的数列
将其分为k个数列(不一定有序)
这k个数列的大小的lcm不同的方案数
一个很明显的DP(类似背包)
实现方式见代码
/**************************************************************
Problem: 1025
User: wiiind
Language: C++
Result: Accepted
Time:40 ms
Memory:9120 kb
****************************************************************/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int n;
const int maxn=1001;
bool v[maxn];
int pri[maxn];
int prinum;
long long f[maxn][maxn];
int main(){
scanf ("%d",&n);
prinum=0;
for (register int i=2;i<=1000;++i){
if (!v[i]) pri[++prinum]=i;
for (int j=1;j<=prinum&&i*pri[j]<=1000;++j){
v[i*pri[j]]=1;
if (!(i%pri[j])) break ;
}
}
f[0][0]=1;
for (register int i=1;i<=prinum;++i){
for (int j=0;j<=n;++j) f[i][j]=f[i-1][j];
for (int j=pri[i];j<=n;j*=pri[i]) for (int k=0;k<=n-j;++k) f[i][k+j]+=f[i-1][k];
}
long long ans=0;
for (register int i=0;i<=n;++i) ans+=f[prinum][i];
printf ("%lld",ans);
return 0;
}
BZOJ 1026 windy数(计数DP)
Description
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
Input
包含两个整数,A B。
Output
一个整数
Sample Input
【输入样例一】
1 10
【输入样例二】
25 50
Sample Output
【输出样例一】
9
【输出样例二】
20
HINT
【数据规模和约定】
100%的数据,满足 1 <= A <= B <= 2000000000 。
一道经典的计数DP
注意压界问题
/**************************************************************
Problem: 1026
User: wiiind
Language: C++
Result: Accepted
Time:40 ms
Memory:824 kb
****************************************************************/
#include<cstdio>
#include<memory.h>
#include<algorithm>
int f[20][20];
void init()
{
memset(f,0,sizeof(f));
for(int i=0;i<10;i++)
f[1][i]=1;
for(int i=2;i<=10;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
if(abs(j-k)>=2)
f[i][j]+=f[i-1][k];
}
int solve(int x)
{
int ans=0,len=0;
int b[20];
while (x>0)
{
b[++len]=x%10;
x/=10;
}
for (int i=1;i<len;i++)
for (int j=1;j<10;j++)
ans+=f[i][j];
for (int i=1;i<b[len];i++)
ans+=f[len][i];
for (int i=len-1;i>0;i--)
{
for (int j=0;j<b[i];j++)
if (abs(j-b[i+1])>=2)
ans+=f[i][j];
if (abs(b[i]-b[i+1])<2)
break;
}
return ans;
}
int main()
{
int x,y;
init();
scanf("%d%d",&x,&y);
printf("%d",solve(y+1)-solve(x));
}
标签:2009,int,样例,SCOI,windy,Output,Input,include 来源: https://blog.csdn.net/luowiiind/article/details/99987730