UVA 10626--Buying Coke+记忆化搜索+DP

题目链接:点击进入

原来定义状态dp[n][n1][n5][n10]表示购买n瓶可乐后剩余1,5,10分硬币n1,n5,n10个时花费硬币数最小的数量.然后状态转移是:1.8个一分硬币购买第n瓶可乐,t=dp[n-1][n1+8][n5][n10]+8; 2.一个五分和3个1分,t=dp[n-1][n1+3][n5+1][n10]+4; 3.两个5分t=dp[n-1][n1][n5+2][n10]; 4.一个10分,t=dp[n-1][n5][n10+1].

对于第一二种dp[n][n1][n5][n10]=min(t,dp[n][n1][n5][n10])

对于3,4种:dp[n][n1+2][n5][n10]=min(dp[n][n1+2][n10],t).

然后交上去就超时了,后面看了一下别人的思路,发送自己少考虑了一种情况: 投3个1分和1个10,找回1个5分.然后可以用记忆化搜索来写.定义状态dp[n1][n5][n10]表示在状态(n1,n5,n10)下购买一瓶可乐所需要的最少硬币数.

代码如下:

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

#define INF 0x3f3f3f3f

int dp[780][170][60];

int solve(int n,int n1,int n5,int n10)
{
     if(dp[n1][n5][n10]!=-1)
          return dp[n1][n5][n10];
    if(n==0)
       return 0;
    int Min=INF;
    if(n1>=8)
    {
         int t=solve(n-1,n1-8,n5,n10)+8;
         Min=min(Min,t);
    }
    if(n1>=3&&n5>=1)
    {
         int t=solve(n-1,n1-3,n5-1,n10)+4;
         Min=min(Min,t);
    }
   /* if(n1>=3&&n10>=1)
    {
        int t=solve(n-1,n1-3,n5+1,n10-1)+4;
        Min=min(t,Min);
    }*/
    if(n5>=2)
    {
        int t=solve(n-1,n1+2,n5-2,n10)+2;
        Min=min(t,Min);
    }
    if(n10>=1)
    {
        int t=solve(n-1,n1+2,n5,n10-1)+1;
        Min=min(Min,t);
    }
    return dp[n1][n5][n10]=Min;
}

int main()
{
     // freopen("in.txt","r",stdin);
      int  t,n,n1,n5,n10;
      scanf("%d",&t);
      while(t--)
    {
           scanf("%d%d%d%d",&n,&n1,&n5,&n10);
           memset(dp,-1,sizeof(dp));
           int ans=solve(n,n1,n5,n10);
           printf("%d\n",ans);
      }
  return 0;
}
时间: 2024-08-28 22:09:38

UVA 10626--Buying Coke+记忆化搜索+DP的相关文章

UVA 10626 Buying Coke (记忆化)

地址:点击打开链接 题意:就是买一个售价8分的饮料,然后你有的硬币有1,5,10分三种. 然后问买c瓶饮料,一次一次买,你最小的投币次数. 我们可以有几种方法:1:投8个一分  2:投一个5分的3个1分的 3:投一个10分的找3个一分的 4:投一个10分的3个一分的,找一个5分的 还有其他方案但是不是太划算. #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #in

uva 10626 Buying Coke (DP记忆化搜索)

uva 10626 Buying Coke I often buy Coca-Cola from the vending machine at work. Usually I buy several cokes at once, since my working mates also likes coke. A coke in the vending machine costs 8 Swedish crowns, and the machine accept crowns with the va

uva10626 - Buying Coke(记忆话搜索)

题目:uva10626 - Buying Coke(记忆话搜索) 题目大意:给你3种价值的硬币, 1, 5, 10现在要求你取自动售卖机买可乐,一瓶可乐价值8,给你要求买的可乐的数目,和三种硬币的数目,问你最少需要投多少硬币.自动售卖机会根据你投入的钱来找零,可以的话找出的零钱硬币会最少. 解题思路: 这题之前没有想到可乐的已经购买瓶数是隐含在剩余的硬币情况中,换句话说就是你买了多少瓶可乐,不论用什么方式买,剩余的硬币的情况总能反映买了多少瓶可乐.所 以数组开3维就可以了.而且要注意还有 1 个

UVA - 10118Free Candies(记忆化搜索)

题目:UVA - 10118Free Candies(记忆化搜索) 题目大意:给你四堆糖果,每个糖果都有颜色.每次你都只能拿任意一堆最上面的糖果,放到自己的篮子里.如果有两个糖果颜色相同的话,就可以将这对糖果放进自己的口袋.自己的篮子最多只能装5个糖果,如果满了,游戏就结束了.问你能够得到的最多的糖果对数. 解题思路:这题想了好久,好不容易把状态想对了,结果脑子发热,又偏离了方向.dp[a][b][c][d]:四堆糖果现在在最上面的是哪一个.因为下面的糖果如果确定了,那么接下了不管你怎么取,最优

hdu 4960 记忆化搜索 DP

Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 490    Accepted Submission(s): 180 Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morni

uva 10626 Buying Coke (DP + 记忆化搜索)

Problem D Buying Coke Input: Standard Input Output: Standard Output Time Limit: 2 Seconds I often buy Coca-Cola from the vending machine at work. Usually I buy several cokes at once, since my working mates also likes coke. A coke in the vending machi

UVA 707 - Robbery(记忆化搜索)

UVA 707 - Robbery 题目链接 题意:在一个w * h的图上,t个时刻,然后知道一些信息,每个时刻没有小偷的矩阵位置,问哪些时刻可以唯一确定小偷位置,和确定小偷是否已经逃走,如果没逃走,但是也没有时刻可以可以确定小偷位置,就是不知到 思路:记忆化搜索,dp[x][y][ti]表示在x,y位置,ti时刻时候,小偷是否可能出现在这个位置,1表示有可能,0表示没可能,由于小偷一次最多只能上下左右走一步或者不走,所以去dfs一遍即可 最后判断的时候,如果有一个时刻没有一个1,就表示已经逃走

HDU 1078 FatMouse and Cheese(记忆化搜索DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078 题目大意:一个n*n的图,每个点都有奶酪,老鼠从(0,0)开始走,每次最多只能走k步就要停下来,停下的这个位置的奶酪数只能比上一个停留的位置大,并获取其奶酪,每次只能水平或垂直走,问最多能得到的奶酪. 解题思路:记忆化搜索,这方面还是写的太少,还要看别人才会,这个就当个例子参考吧. 1 #include<cstdio> 2 #include<cstring> 3 #include

UVa 1629 Cake slicing (记忆化搜索)

题意:一个矩形蛋糕上有好多个樱桃,现在要做的就是切割最少的距离,切出矩形形状的小蛋糕,让每个蛋糕上都有一个樱桃,问最少切割距离是多少. 析:很容易知道是记忆化搜索,我们用dp[u][d][l][r]来表示,上界是u,下界是d,左边是l,右边是r,然后不断切割,不过要注意切的时候是按缝隙切, 缝隙多一条,那么我们可以补上一条,用0来补齐,然后就进行计算就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #in