zoukankan      html  css  js  c++  java
  • Tyche 2147 旅行

    题目描述

     

    你有m元钱,将要游览n个国家。每一个国家有一种商品,其中第i个国家商品的单价为ai元。每到一个国家,你会用手上的钱疯狂购买这个国家的商品,直到剩余的钱无法购买为止。

    现在你要决定游览这n个国家的顺序,使得游览完n个国家后剩余的钱最多。

    输入描述

     

    输入包含两行。

    第一行两个整数n和m,表示国家数和钱数。

    第二行n个整数分别为每个国家商品的单价。

    输出描述

     

    一行一个整数,表示最多剩余多少元钱。

    样例输入

     

    3 31
    5 7 11
    
    样例输出

     

    4
    
    注释

     

    1≤n≤1000,1≤m≤5000,1≤ai≤1000000000

    解题思路

    第一遍看题以为是贪心,只想到了排序,但是不知道该如何最优。

    考试结束之后得知正解是dp后,我慌了。(其实看数据范围明显是dp

    考虑dp[i][j]表示m取模前i个数得到j是否可行,有两种转移。

    1 a[i]不选dp[i][j]|=dp[i-1][j]

    2 a[i]选 dp[i][j%a[i]]|=dp[i-1][j]

    初态dp[0][m]=dp[0][0]=1

    终态在所有dp[n][j]==1中选最大的j%a[n]

    dp是学不会的,这辈子都不可能。

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 const int N=1005;
     6 int n,m,ans,f[N][5*N],a[N];//f[i][j]表示m取模前i个数得到j是否可行 
     7 bool cmp(int c,int d)
     8 {
     9     return c>d;
    10 }
    11 int main()
    12 {
    13     scanf("%d%d",&n,&m);
    14     for(int i=1;i<=n;i++)
    15         scanf("%d",a+i);
    16     sort(a+1,a+n+1,cmp);
    17     f[0][m]=1,f[0][0]=1;
    18     for(int i=1;i<=n;i++)
    19         for(int j=0;j<=m;j++)
    20         {
    21             f[i][j]=f[i-1][j];
    22             f[i][j%a[i]]|=f[i-1][j];
    23         }
    24     for(int i=0;i<=m;i++)
    25         if(f[n][i])
    26             ans=max(ans,i%a[n]);
    27     printf("%d
    ",ans);
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    迅雷亲历面试经过,笔试+上机+面试(完整)
    Flash Player安全高级攻略
    EBS查看Report程式所挂在的. 报表名. 组. 责任
    ORACLE常用后台表查询
    Ap_Aging_Report SQL月底结账使用
    2012年最新会计科目表
    如何用sql实现AP_payments中应付余额与GL_balance对应科目余额相同
    SQL应收帐款帐龄报表(AR_Aging_Reporting)
    Navigator: Disable Multiform
    GL: 访问权限集
  • 原文地址:https://www.cnblogs.com/fantasquex/p/9866743.html
Copyright © 2011-2022 走看看