Noip2006普及组

T2

题目描述

    金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过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



DP,01背包:

var
        f:array[0..30000] of longint;
        w,c:array[1..25] of longint;
        i,j,n,v,x:longint;

function max(x,y:longint):longint;
begin
        if x>y then exit(x) else exit(y);
end;

begin
        assign(input,'happy.in'); reset(input);
        assign(output,'happy.out'); rewrite(output);

        readln(v,n);

        for i:=1 to n do
        begin
                readln(w[i],x);
                c[i]:=w[i]*x;
        end;

        for i:=1 to n do
                for j:=v downto w[i] do
                        f[j]:=max(f[j],f[j-w[i]]+c[i]);

        writeln(f[v]);

        close(input); close(output);
end.



T3:

题目描述
    Jam是个喜欢标新立异的科学怪人。他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩。在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母。我们把这样的“数字”称为Jam数字。在Jam数字中,每个字母互不相同,而且从左到右是严格递增的。每次,Jam还指定使用字母的范围,例如,从2到10,表示只能使用{b,c,d,e,f,g,h,i,j}这些字母。如果再规定位数为5,那么,紧接在Jam数字“bdfij”之后的数字应该是“bdghi”。(如果我们用U、V依次表示Jam数字“bdfij”与“bdghi”,则U,且不存在Jam数字P,使U)。你的任务是:对于从文件读入的一个Jam数字,按顺序输出紧接在后面的5个Jam数字,如果后面没有那么多Jam数字,那么有几个就输出几个。

输入
    输入文件count.in 有2行,第1行为3个正整数,用一个空格隔开:s t w(其中s为所使用的最小的字母的序号,t为所使用的最大的字母的序号。w为数字的位数,这3个数满足:1≤s≤26, 2≤w≤t-s ) 第2行为具有w个小写字母的字符串,为一个符合要求的Jam数字。 所给的数据都是正确的,不必验证。

输出
    输出文件count.out 最多为5行,为紧接在输入的Jam数字后面的5个Jam数字,如果后面没有那么多Jam数字,那么有几个就输出几个。每行只输出一个Jam数字,是由w个小写字母组成的字符串,不要有多余的空格。

样例输入
2 10 5
bdfij

样例输出
bdghi
bdghj
bdgij
bdhij
befgh


这道题目真心水,会Dfs的应该都会做吧,会全排列的分分钟秒杀吧,只输出前5个——这...

var
        tot,s,t,w,i:Longint;
        st:string;
        bz:array['a'..'z'] of boolean;
        a:array[1..5] of string;

Procedure print;
var
        i:Longint;
begin
        for i:=1 to tot do
                writeln(a[i]);
        halt;
end;

Procedure dfs(k:Longint; str:string; ch:char);
var
        i:Char;
begin
        if k<>1 then
                if str<copy(st,1,length(str)) then exit;
        if k>2 then
                if (ord(str[k-1])-96)-(ord(str[k-2])-96)>t-w then exit;<span style="white-space:pre">	</span>//两个优化,可以0ms内秒杀。

        if k>w then
        begin
                if str>st then
                begin
                        inc(tot);
                        a[tot]:=str;

                        if tot=5 then print;
                end;
                exit;
        end;

        for i:=ch to chr(t+96) do
                if bz[i] then
                begin
                        bz[i]:=false;
                        dfs(k+1,str+i,succ(i));
                        bz[i]:=true;
                end;
end;

begin
        assign(input,'count.in'); reset(input);
        assign(output,'count.out'); rewrite(output);

        readln(s,t,w);
        readln(st);

        if t=w then halt;

        fillchar(bz,sizeof(bz),true);

        dfs(1,'',st[1]);

        print;

        close(input); close(output);
end.


T4:

题目描述
    给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是:
 1,3,4,9,10,12,13,…
(该序列实际上就是:3^0,3^1,3^0+3^1,3^2,3^0+3^2,3^1+3^2,3^0+3^1+3^2,…)
请你求出这个序列的第N项的值(用10进制数表示)。
例如,对于k=3,N=100,正确答案应该是981。


输入
输入文件sequence.in 只有1行,为2个正整数,用一个空格隔开:
k N
(k、N的含义与上述的问题描述一致,且3≤k≤15,10≤N≤1000)。

输出
输出文件sequence.out 为计算结果,是一个正整数(在所有的测试数据中,结果均不超过2.1*10^9)。(整数前不要有空格和其他符号)。

样例输入
3 100

样例输出
981


这道题目也真的,真的,真的水啊,这整套题目都是这么水啊,这道题真的只用模拟一下就行了

3^0,3^1,3^0+3^1,3^2,3^2+3^0,3^2+3^1,3^2+3^1+3^0

规律就是,以k的n次方划分阶段,从第二个数其,k^n+f[i-1]=f[i],第I个数是由k^n+i-1前面任何与一个数得来的,例如3^2,后面的三个数都是2^3加上f[1],f[2],f[3]得来的。

代码:

var
        f:array[1..1050] of int64;
        k,n,i,j,t,p:Longint;
begin
        assign(input,'sequence.in'); reset(input);
        assign(output,'sequence.out'); rewrite(output);

        readln(k,n);
        f[1]:=1;
        f[2]:=k;
        f[3]:=k+1;
        i:=4;
        t:=1;
        while i<=n do
        begin
                inc(t);
                f[i]:=1;
                for j:=1 to t do
                        f[i]:=f[i]*k;
                p:=i;
                for j:=1 to i-1 do
                begin
                        inc(p);
                        f[p]:=f[i]+f[j];
                end;
                i:=p+1;
        end;
        writeln(f[n] mod (maxLongint+1));

        close(input); close(output);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值