Loading

NOIP2002提高組 均分紙牌

2011年10月09日 02:49

[问题描述]
有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。
移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如 N=4,4 堆纸牌数分别为:
① 9 ② 8 ③ 17 ④ 6
移动3次可达到目的:
从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。

[输 入]
N(N 堆纸牌,1 <= N <= 100)
A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)

[输 出]
输出至屏幕。格式为:
所有堆均达到相等时的最少移动次数。‘

[输入输出样例]
4
9 8 17 6

[输入输出样例]
3

解析見http://www.byvoid.com/blog/noip-allsolutions/

 

#include <iostream>
#include <cstdio>
using namespace std;

int N,avg,ans;
int S[101];

int main()
{
    int i;
    freopen("jfzp.in","r",stdin);
    freopen("jfzp.out","w",stdout);
    cin >> N;
    for (i=1;i<=N;i++)
    {
        cin >> S[i];
        avg+=S[i];
    }
    avg/=N;
    for (i=1;i<N;i++)
    {
        if (S[i]!=avg)
        {
            S[i+1]+=S[i]-avg;
            S[i]=avg;
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 20 0.030 s 273 KB 0
2 正确 20 0.002 s 273 KB 0
3 正确 20 0.011 s 273 KB 0
4 正确 20 0.001 s 273 KB 0
5 正确 20 0.001 s 273 KB 0

运行完成

运行时间 0.045 s

平均内存使用 273 KB

测试点通过状况 AAAAA

得分:100

恭喜你通过了全部测试点!

Tags: NOIP c++ 貪心
评论(1) 阅读(5129)

NOIP2000提高組 進制轉換

2011年10月09日 02:33

描述 Description

我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式。例如,123可表示为1*10^2+2*10^1+3*10^0这样的形式。
与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置的(值-1)为指数,以2为底数的幂之和的形式。一般说来,任何一个正整 数R或一个负整数-R都可以被选来作为一个数制系统的基数。如果是以R或-R为基数,则需要用到的数码为0,1,....R-1。例如,当R=7时,所需 用到的数码是0,1,2, 3,4,5和6,这与其是R或-R无关。如果作为基数的数绝对值超过10,则为了表示这些数码,通常使用英文字母来表示那些大于9的数码。例如对16进制 数来说,用A表示10,用B表示11,用C表示12,用D表示13,用E表示14,用F表示15。在负进制数中是用-R作为基数,例如-15(+进制)相 当于110001(-2进制),
并且它可以被表示为2的幂级数的和数:
110001=1*(-2)^5+1*(-2)^4+0*(-2)^3+0*(-2)^2+0*(-2)^1+1*(-2)^0
问题求解:
设计一个程序,读入一个十进制数的基数和一个负进制数的基数,并将此十进制数转换为此负进制下的数:-R∈{-2,-3,-4,....-20}

输入格式 Input Format

输入文件有若干行,每行有两个输入数据。
第一个是十进制数N(-32768<=N<=32767); 第二个是负进制数的基数-R。

输出格式 Output Format

输出此负进制数及其基数,若此基数超过10,则参照16进制的方式处理。【具体请参考样例】

样例输入 Sample Input

30000 -2
-20000 -7
28800 -16
-25000 -16

样例输出 Sample Output

30000=11011010101110000(base -2)
-20000=263526(base -7)
28800=19180(base -16)
-25000=7FB8(base -16)

 

【分析】

比較基礎的題,只要注意整除函數即可。

以下代碼是BYVoid(www.byvoid.com)大牛的:

#include <iostream>
#include <cstdio>
using namespace std;
int N,M,base;

inline int Div(int a,int b)
{
	int n;
	n=a/b;
	if (n*b<=a)
		return n;
	return n+1;
}

void work()
{
	int num[100];
	int top=0;
	if(N==0)
	{
		cout<<0;
	}
	int P;
	while (N)
	{
		P=Div(N,base);
		num[++top]=N-P*base;
		N=P;
	}
	for (;top>=1;top--)
	{
		if (num[top]<10)
			cout<<num[top];
		if (num[top]>=10)
			cout<<(char)(num[top]-10+'A');
	}
		cout<<"(base "<<base<<")"<<endl;
}

int main()
{
	freopen("fjz.in","r",stdin);
	freopen("fjz.out","w",stdout);
	while(cin>>N)
	{
		cin>>base;
		M=N;
		cout<<N<<"=";
		work();
	}
	return 0;
}

 

 

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 273 KB 0
2 正确 10 0.000 s 273 KB 0
3 正确 10 0.000 s 273 KB 0
4 正确 10 0.000 s 273 KB 0
5 正确 10 0.000 s 273 KB 0
6 正确 10 0.000 s 273 KB 0
7 正确 10 0.000 s 273 KB 0
8 正确 10 0.000 s 273 KB 0
9 正确 10 0.000 s 273 KB 0
10 正确 10 0.000 s 273 KB 0

运行完成

运行时间 0.003 s

平均内存使用 273 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

 

Tags: NOIP c++
评论(1) 阅读(2045)

NOIP2001提高組 一元三次方程求解

2011年10月08日 03:41

问题描述
有形如:ax3+bx2+cx+d=0  这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d  均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。
提示:记方程f(x)=0,若存在2个数x1和x2,且x1<x2,f(x1)*f(x2)<0,则在(x1,x2)之间一定有一个 根。

样例
输入:1   -5   -4   20
输出:-2.00   2.00   5.00

【分析】

由於精度不大,直接枚舉即可。

一下代碼參考了BYVoid(http://www.byvoid.com)的代碼~他的代碼比我的簡練多了~

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
	double a,b,c,d,x,v;
	int X;
	freopen("3cfc.in","r",stdin);
	freopen("3cfc.out","w",stdout);
	cin>>a>>b>>c>>d;
	for (X=-10000;X<=10000;x=(++X)/100.0)
	{
		v=a*x*x*x+b*x*x+c*x+d;
		if (v>=-0.01 && v<=0.01)	
			printf("%.2lf ",x);	
	}
	return 0;
}

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 20 0.027 s 273 KB 0
2 正确 20 0.001 s 273 KB 0
3 正确 20 0.001 s 273 KB 0
4 正确 20 0.001 s 273 KB 0
5 正确 20 0.001 s 273 KB 0

运行完成

运行时间 0.031 s

平均内存使用 273 KB

测试点通过状况 AAAAA

得分:100

恭喜你通过了全部测试点!

 

Tags: NOIP c++ 枚舉 模擬
评论(2) 阅读(3357)

NOIP2004提高組 合併果子

2011年10月08日 03:26

【问题描述】
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
【输入文件】
输入文件fruit.in包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
【输出文件】
输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
【样例输入】
3
1 2 9
【样例输出】
15
【数据规模】

对于30%的数据,保证有n<=1000:
对于50%的数据,保证有n<=5000;
对于全部的数据,保证有n<=10000。

【分析】

貪心,每次找到最小的兩堆果子進行合併。

不要把本題看成石子歸併。

我用的是鏈表,全過了,但是速度較慢~

#include <fstream>
using namespace std;	
ifstream fin("fruit.in");
ofstream fout("fruit.out");
class data
{
public:
	int key;
	//Other members HERE...
	int sen;//前驱
	int next;//后继
};
data A[200000];
int top;//链表中元素的个数

void Insert(int key)
{
	int point=0;
	while (key>A[point].key)
	{
		point=A[point].next;
	}
	//Create a new node
	A[top].key=key;
	A[top].next=point;
	A[top].sen=A[point].sen;
	
	A[point].sen=top;//后继的前驱等于自己
	
	A[A[top].sen].next=top;//前驱的后继等于自己
	
	top++;
}

void DeleteOne(int key)
{
	int point=A[0].next; 
	while(A[point].next!=-1)
	{
		if(A[point].key==key)
		{
			A[A[point].sen].next=A[point].next; //自己前驱的后继等于自己的后继
			A[A[point].next].sen=A[point].sen;  //自己后继的前驱等于自己的前驱
			return; //跳出函数
		}
		point=A[point].next;
	}
}

void print()
{
	int point=A[0].next; 
	while(A[point].next!=-1)
	{
		fout<<A[point].key<<endl;
		point=A[point].next;
	}
}
void debug()
{
	for (int i=0;i<top;i++)
		fout<<i<<" "<<A[i].key<<" "<<A[i].sen<<" "<<A[i].next<<endl;
}

int GetMinElem()
{
	int point=A[0].next;
	return A[point].key;
}

int main()
{

	//Initialize
	A[0].key=-1;A[0].next=1;A[0].sen=-1;
	A[1].key=0Xfffffff;A[1].next=-1;A[0].sen=0;
    top=2;
	int num,key;
	fin>>num;
	for (int i=0;i<num;i++)
	{
		fin>>key;
		Insert(key);//插入一个关键字
	}
	
	int liu=num;
	int cost=0;
	//debug();
	while (liu!=1)
	{
		int m=GetMinElem();
		DeleteOne(m);
		int n=GetMinElem();
		DeleteOne(n);
		//fout<<m<<" "<<n<<endl<<endl;
		cost+=(m+n);
		Insert(m+n);
		liu--;
	}
	//print();
	fout<<cost<<endl;
	return 0;
}

 

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.000 s 2614 KB 0
2 正确 10 0.002 s 2614 KB 0
3 正确 10 0.002 s 2614 KB 0
4 正确 10 0.043 s 2614 KB 0
5 正确 10 0.096 s 2614 KB 0
6 正确 10 0.403 s 2614 KB 0
7 正确 10 0.503 s 2614 KB 0
8 正确 10 0.396 s 2614 KB 0
9 正确 10 0.500 s 2614 KB 0
10 正确 10 0.508 s 2614 KB 0

运行完成

运行时间 2.453 s

平均内存使用 2614 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

 

Tags: noip 貪心 c++
评论(1) 阅读(1445)

NOIP2006普及組 明明的隨機數

2011年10月08日 03:10

【问题描述】
    明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数( N ≤ 100 ),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按 照 排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。

【输入格式】
     输入文件 random.in 有 2 行,第 1 行为 1 个正整数,表示所生成的随机数的个数:N

     第 2 行有 N 个用空格隔开的正整数,为所产生的随机数。

【输出格式】
     输出文件 random.out 也是 2 行,第 1 行为 1 个正整数 M ,表示不相同的随机数的个数。第 2 行为 M 个用空格隔开的正整数,为从小到大排好序的不相同的随机数。

【输入输出样例】
 
输入:
10
20 40 32 67 40 20 89 300 400 15
 

输出:
8
15 20 32 40 67 89 300 400

【分析】

水題,直接模擬。

//NOIP2006-Junior-Random
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

int Compare(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}

int main()
{
	freopen("random.in","r",stdin);
	freopen("random.out","w",stdout);
	int num[101]={0};
	int n;
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&num[i]);
	int reduce=0;
	for (int i=1;i<=n;i++)
		for (int j=i+1;j<=n;j++)
			if (num[j]!=1001 && num[i]!=1001 && num[j]==num[i])
				{
					num[j]=1001;
					reduce++;
				}
	qsort(num+1,n,sizeof(int),Compare);
	cout<<n-reduce<<endl;
	for(int i=1;i<=n-reduce;i++)
		cout<<num[i]<<" ";
	cout<<endl;
	return 0;
}

 

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.018 s 273 KB 0
2 正确 10 0.001 s 273 KB 0
3 正确 10 0.001 s 273 KB 0
4 正确 10 0.001 s 273 KB 0
5 正确 10 0.001 s 273 KB 0
6 正确 10 0.001 s 273 KB 0
7 正确 10 0.001 s 273 KB 0
8 正确 10 0.001 s 273 KB 0
9 正确 10 0.001 s 273 KB 0
10 正确 10 0.001 s 273 KB 0

运行完成

运行时间 0.024 s

平均内存使用 273 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

Tags: NOIP c++ 模擬
评论(1) 阅读(10373)

NOIP2006普及組 開心的金明

2011年10月08日 02:59

【问题描述】
     金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎 么布置,你说了算,只要不超过 N 元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的 N 元。于是,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。

设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j1 , j2 ,……, jk ,则所求的总和为:

v[j1]*w[j1]+v[j2]*w[j2]+ … +v[jk]*w[jk] 。(其中 * 为乘号)

请你帮助金明设计一个满足要求的购物单。

【输入格式】
     输入文件 happy.in 的第 1 行,为两个正整数,用一个空格隔开:

N m

(其中 N ( < 30000 )表示总钱数, m ( <25 )为希望购买物品的个数。)

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 2 个非负整数

v p

(其中 v 表示该物品的价格 (v<=10000) , p 表示该物品的重要度 (1~5) )

【输出格式】
     输出文件 happy.out 只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值( <100000000 )。

【输入输出样例】
 
输入:
1000 5
800 2
400 5
300 5
400 3
200 2
 

输出:
3900

#include <iostream>
#include <cstdio>
using namespace std;
int TolM;//總錢數
int TolThing;//總物品
int F[26][100001];
class THING
{
public: 
	int v;//價格
	int p;//重要度
}T[25];

int getval(int i)
{
	return (T[i].v*T[i].p);
}

void init()
{
	cin>>TolM>>TolThing;
	for (int i=1;i<=TolThing;i++)
	{
		cin>>T[i].v>>T[i].p;
	}
	fclose(stdin);
	return;
}

void predp()
{
	int i,j;
	for (i=1;i<=TolThing;i++)
		for (j=1;j<=TolM;j++)
			F[i][j]=0;
	
	int q=getval(1);
	for (i=T[1].v;i<=TolM;i++)
	{
		F[1][i]=q;
	}
	return;
}

void print()
{
	int i,j;
	for (i=1;i<=TolThing;i++)
	{
		for (j=1;j<=TolM;j++)
			cout<<F[i][j]<<" ";
		cout<<endl;	
	}
	cout<<endl;
}

void dp()
{
	int i,j;
	for (i=2;i<=TolThing;i++)
	{
		for (j=1;j<=TolM;j++)
		{
			if (T[i].v>j)
				F[i][j]=F[i-1][j];
			else 
				F[i][j]=
				((F[i-1][j])>(F[i-1][j-T[i].v]+getval(i))?
				(F[i-1][j]):(F[i-1][j-T[i].v]+getval(i)));
		}
	}
}

int main()
{
	freopen("happy.in","r",stdin);
	freopen("happy.out","w",stdout);
	init();
	predp();
	dp();
	//print();
	cout<<F[TolThing][TolM]<<endl;
	return 0;
}

 

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.062 s 10428 KB 0
2 正确 10 0.001 s 10428 KB 0
3 正确 10 0.001 s 10428 KB 0
4 正确 10 0.001 s 10428 KB 0
5 正确 10 0.004 s 10428 KB 0
6 正确 10 0.003 s 10428 KB 0
7 正确 10 0.004 s 10428 KB 0
8 正确 10 0.005 s 10428 KB 0
9 正确 10 0.007 s 10428 KB 0
10 正确 10 0.001 s 10428 KB 0

运行完成

运行时间 0.089 s

平均内存使用 10428 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

Tags: NOIP c++ 動態規劃
评论(0) 阅读(1568)

NOIP2002普及組 選數

2011年10月08日 02:49

[问题描述]:


已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34。
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29)。
[输入]:
键盘输入,格式为:
n , k (1<=n<=20,k<n)
x1,x2,…,xn (1<=xi<=5000000)

[输出]:
格式为:一个整数(满足条件的种数)。
 
[输入输出样例]:
输入:choose.in
4 3
3 7 12 19
输出:choose.out
1

【分析】
排列組合問題,直接深度優先搜索(遞歸)即可。

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int sum=0;//當前總和
int num[21];
int n,k;
int tot=0;

bool prime(int num)
{
	if (num==1)return false;
	for (int i=2;i<=(int)sqrt(double(num));i++)
		if (num%i==0)
			return false;
	return true;	
}


void dg(int dep,int loc)
{
	if(k-dep>n-loc) return;
	if (dep==k+1)
	{
		if (prime(sum))
			tot++;
	}
	if (dep<k+1)
	{
		for (int i=loc;i<=n;i++)
		{
			sum+=num[i];
			dg(dep+1,i+1);
			sum-=num[i];
		}
	}
}

int main()
{
	freopen("choose.in","r",stdin);
	freopen("choose.out","w",stdout);
	cin>>n>>k;
	for (int i=1;i<=n;i++)
		cin>>num[i];
	dg(1,1);
	cout<<tot<<endl;
	return 0;
}

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 20 0.026 s 275 KB 0
2 正确 20 0.001 s 275 KB 0
3 正确 20 0.001 s 275 KB 0
4 正确 20 0.001 s 275 KB 0
5 正确 20 0.001 s 275 KB 0

运行完成

运行时间 0.028 s

平均内存使用 275 KB

测试点通过状况 AAAAA

得分:100

恭喜你通过了全部测试点!


Tags: c++ NOIP 深度優先搜索
评论(0) 阅读(1369)

NOIP2005 普及组 采药

2011年10月08日 02:26

【问题描述】

    辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难 题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段 时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”

如果你是辰辰,你能完成这个任务吗?

【输入文件】

   输入文件的第一行有两个整数 T ( 1 <= T <= 1000 )和 M ( 1 <= M <= 100 ),用一个空格隔开, T 代表总共能够用来采药的时间, M 代表山洞里的草药的数目。接下来的 M 行每行包括两个在 1 到 100 之间(包括 1 和 100 )的整数,分别表示采摘某株草药的时间和这株草药的价值。

【输出文件】

输出文件包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

【样例输入】

70 3
71 100
69 1
1 2

【样例输出】

3

【数据规模】

对于 30% 的数据, M <= 10 ;

对于全部的数据, M <= 100 。

 

【分析】

本题是经典的0/1背包问题,直接DP即可。

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef unsigned short int usint;

class medic
{
public:
	usint t; //Time
	usint v; //Value
}Med[101];
usint T,M;//T: Total Time , M: The number of the medicine.
usint F[101][1001];

void init()
{
	cin>>T>>M;
	//初始化二維表
	for (usint i=1;i<=M;i++)
		for (usint j=1;j<=T;j++)
			F[i][j]=0;
	//從文件中讀入	
	for(usint i=1;i<=M;i++)
		cin>>Med[i].t>>Med[i].v;
	//預處理動態規劃 Pre-Dynamic Programing
	for (usint i=Med[1].t;i<=T;i++)
		F[1][i]=Med[1].v;
	return;
}

void Dynamic()
{
	usint i,j;
	for (i=2;i<=M;i++)
	{
		for(j=1;j<=T;j++)
		{
			if(Med[i].t>j)
				F[i][j]=F[i-1][j];
			else
			{
				F[i][j]=( (F[i-1][j]) > (F[i-1][j-Med[i].t]+Med[i].v) ?
					  (F[i-1][j]) : (F[i-1][j-Med[i].t]+Med[i].v) );
			}
		}
	}
}

int main()
{
	freopen("medic.in","r",stdin);
	freopen("medic.out","w",stdout);
	init();
	Dynamic();
	cout<<F[M][T]<<endl;
	return 0;
}

正在连接评测机...

 

已连接到评测机

GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty

正在编译...

编译成功

 

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.024 s 464 KB 0
2 正确 10 0.001 s 464 KB 0
3 正确 10 0.002 s 464 KB 0
4 正确 10 0.002 s 464 KB 0
5 正确 10 0.002 s 464 KB 0
6 正确 10 0.002 s 464 KB 0
7 正确 10 0.002 s 464 KB 0
8 正确 10 0.002 s 464 KB 0
9 正确 10 0.002 s 464 KB 0
10 正确 10 0.001 s 464 KB 0

运行完成

运行时间 0.041 s

平均内存使用 464 KB

测试点通过状况 AAAAAAAAAA

得分:100

恭喜你通过了全部测试点!

Tags: c++ NOIP 動態規劃
评论(0) 阅读(2301)