洛谷 1108 低价购买

http://www.luogu.org/problem/show?pid=1108#
第一问就是裸的最长下降子序列
第二问比较难,看了题解想了好久才明白,可以加一个t[i]数组表示1到i取最长下降子序列的方案数,显然如果f[i]==1则t[i]=1,然后j从1到i-1循环,f[i]==f[j]+1&&a[i]< a[j]时说明可以从1到j的最长子序列后加一个a[i]即加上t[j]个方案数,这里要去除“看起来一样”的方案,当f[i]==f[j]&&a[i]==a[j]时,f[j]即重复的,直接t[j]=0。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[5010],a[5010],t[5010];
int n,ans1,ans2;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        f[i]=1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i-1;j++)
        {
            if(a[i]<a[j])
            f[i]=max(f[i],f[j]+1);
        }
        if(f[i]==1)
        t[i]=1;
        for(int j=1;j<=i-1;j++)
        {

            if(f[i]==f[j]+1&&a[i]<a[j])
            t[i]+=t[j];
            if(f[i]==f[j]&&a[i]==a[j])
            t[j]=0;
        }
    }
    for(int i=1;i<=n;i++)
    ans1=max(f[i],ans1);
    for(int i=1;i<=n;i++)
    if(f[i]==ans1)
    ans2+=t[i];
    printf("%d %d",ans1,ans2);
    return 0;
}
洛谷“买铅笔”题目(P1909 [NOIP 2016 普及组])的相关内容如下: ### 题目描述 P老师需要去商店买n支铅笔作为小朋友们参加NOIP的礼物。商店一共有 3 种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起见,P老师决定只买同一种包装的铅笔[^2]。 ### 解题思路 解题关键在于一个一个比较不同包装铅笔的价格,然后找到价格最少的。用需要的铅笔数去和每种包装里铅笔数取模,如果结果为0,说明正好达到需要的数量,算出买这种包装铅笔需要的价格;如果结果不等于0,说明需要多买一份(向上取整),通过取模加1算出需要买的份数,进而算出买这种包装铅笔需要的价格,最后输出最少价钱[^3]。 ### 代码示例 #### C++代码 ```cpp #include<iostream> using namespace std; int main() { int n,s[4],p[4],t[4],f[4],i; //n指老师要买的铅笔数,i是循环用的。 //s指每袋笔的数量,p指每袋笔的价格,t指最后需要的钱,f指袋数。 cin>>n; for(i=1;i<=3;i++) cin>>s[i]>>p[i]; for(i=1;i<=3;i++) { f[i]=n/s[i];//基本袋数。 if(n%s[i]>0) f[i]++;//如果不是倍数要加一。 t[i]=f[i]*p[i]; } //下面就是作比较,谁小(省钱)输出谁。 if(t[1]<t[2]) if(t[1]<t[3]) cout<<t[1]; else cout<<t[3]; else if(t[2]<t[3]) cout<<t[2]; else cout<<t[3]; return 0; } ``` #### Java代码 ```java import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int[] array=new int[7]; for(int i=0;i<7;i++) { array[i]=sc.nextInt(); } int cost1=cost(array[0],array[1],array[2]); int cost2=cost(array[0],array[3],array[4]); int cost3=cost(array[0],array[5],array[6]); if(cost1>cost2) cost1=cost2; if(cost1>cost3) cost1=cost3; System.out.println(cost1); } public static int cost(int x,int y,int z) { int cost; if(x%y==0) cost=x/y*z; else cost=(x/y+1)*z; return cost; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值