problem 1558
来源:互联网 发布:淘宝推广用什么软件好 编辑:程序博客网 时间:2024/06/03 18:20
Euro Efficiency
题目讲了一大通,其实就是在说找硬币。转化成数学语言就是:
先给定6个数a[0…6],对于所有满足n =
输出max{ r[n] | 1 <= n <= 100 }与
考虑DP,容易看出r[n]=min{ r[|n+/-a[0...6]|] }+1。碰到了一个问题,当去求r[n]的时候需要同时用到比n大(n+a[0...6])的和比n小(|n-a[0...6]|有可能比n小)的,也就是说按传统DP从1到100递增的顺序填r[n]是不可行的。
那么就想到用递归,结果搞了半天觉得太麻烦了,理不请楚。
其实问题很简单的。反过来想:初始时候我们已知了r[a[0...6]]=1,那么r[a[0…6]+/-a[0…6]]=2(去掉不满足1<=n<=100的情况),就是从已知的推出未知的。
不断重复如下:
n从0到100;
f = |a[0…6] +/- n|;
if(f > 0 && f <= 100)
r[f] = r[f] > (r[k] + 1) ? r[k] + 1 : r[f];
那么最多要重复多少次呢?显然最多只需做max{ r[n] | 1 <= n <= 100 } 次,不过我们还没有求得,这里采用边算边求的方法。
1558 C 00:00.00 392K
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int a[6];
char r[101];
void solve()
{
int i,j,k,sum = 1,max = 0,cnt = 0;
memset(r,100,sizeof(r));
scanf("%d %d %d %d %d %d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5]);
r[a[0]] = r[a[1]] = r[a[2]] = r[a[3]] = r[a[4]] = r[a[5]] = 1;
while(1)
{
for(j = 0; j < 6; j++)
{
max = 0;
for(k = 1; k <= 100 - a[j]; k++)
{
int f = a[j] + k;
if(f > 0 && f <= 100)
{
r[f] = r[f] > (r[k] + 1) ? r[k] + 1 : r[f];
max = max > r[f] ? max : r[f];
}
f = abs(a[j] - k);
if(f > 0 && f <= 100)
{
r[f] = r[f] > (r[k] + 1) ? r[k] + 1 : r[f];
max = max > r[f] ? max : r[f];
}
}
}
if(max <= ++cnt)
break;
}
for(i = 2; i <= 100; i++)
sum += r[i];
printf("%.2f %d ",sum / 100.0,max);
}
void main()
{
int t;
#ifndef ONLINE_JUDGE
freopen("test.txt","r",stdin);
#include<string.h>
#include<stdlib.h>
#include<math.h>
int a[6];
char r[101];
void solve()
{
int i,j,k,sum = 1,max = 0,cnt = 0;
memset(r,100,sizeof(r));
scanf("%d %d %d %d %d %d",&a[0],&a[1],&a[2],&a[3],&a[4],&a[5]);
r[a[0]] = r[a[1]] = r[a[2]] = r[a[3]] = r[a[4]] = r[a[5]] = 1;
while(1)
{
for(j = 0; j < 6; j++)
{
max = 0;
for(k = 1; k <= 100 - a[j]; k++)
{
int f = a[j] + k;
if(f > 0 && f <= 100)
{
r[f] = r[f] > (r[k] + 1) ? r[k] + 1 : r[f];
max = max > r[f] ? max : r[f];
}
f = abs(a[j] - k);
if(f > 0 && f <= 100)
{
r[f] = r[f] > (r[k] + 1) ? r[k] + 1 : r[f];
max = max > r[f] ? max : r[f];
}
}
}
if(max <= ++cnt)
break;
}
for(i = 2; i <= 100; i++)
sum += r[i];
printf("%.2f %d ",sum / 100.0,max);
}
void main()
{
int t;
#ifndef ONLINE_JUDGE
freopen("test.txt","r",stdin);
#endif
while(scanf("%d",&t)!=EOF )
while(t--)
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
while(scanf("%d",&t)!=EOF )
while(t--)
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
}
}
- problem 1558
- problem
- Problem
- problem
- Problem
- Problem
- Problem
- Problem
- Problem
- Problem
- problem
- Problem
- Problem
- Problem
- Problem
- Problem
- Problem
- Problem
- BSP资源
- Visual Studio 2005 IDE 技巧和窍门
- 3D游戏角色动画
- WinCE5.0中VirtualAlloc内存分配的试验代码
- 常见内部排序算法 简单数组实现与分析(快速(偶原创partition函数,望众高手指正)、归并、希尔、插入、选择、冒泡)
- problem 1558
- 燃烧的远征java(二)-开发环境:征服eclipse
- Delphi MIDAS Architecture
- WinCE线程和内存管理之内存管理
- 学习的流水帐
- 打领带全教程(附领带与衬衣搭配技巧)
- 十商
- Unija - 何去何从
- 完成一个计算24点的代码