uva 10626 Buying Coke

题意:题意:有t组测试数据。每组测试数据有4个数据,分别表示要买几瓶可乐,分别有多少个价值为1,5,10的硬币。每瓶可乐价值为8。问最少需要给自动贩卖机投多少枚硬币。注意,投入硬币后,自动贩卖机会用最少的硬币数给你多的钱。

如果我们开四维的数组,是开不下的,考虑到买了一听可乐之后,价值总是下降的(虽然它的硬币组合是不同的),所以这个状态可以不用记录,只用来判断什么时候结束。注意有一个转移,如果投三个价值1的硬币和一个价值为10的硬币,可以得到一个价值为5的硬币,在一些情况下是可以减少投硬币的个数的。题目给出的数据范围有点问题,一直RE,直到开到这么多。。


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int map[720][220][100];
bool vis[720][220][100];
int dp(int,int,int,int);
int main()
{
    //freopen("10626","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(map,0,sizeof(map));
        memset(vis,0,sizeof(vis));
        int c,n[3]={0};
        scanf("%d%d%d%d",&c,&n[0],&n[1],&n[2]);
        printf("%d\n",dp(c,n[0],n[1],n[2]));
    }
    return 0;
}
int dp(int c,int n1,int n2,int n3)
{
    bool &flag=vis[n1][n2][n3];
    int &res=map[n1][n2][n3];
    if(flag) return res;
    else if(c==0) {flag=1;res=0;return 0;}
    else
    {
        res=1<<30;
        if(n1>=8) res=min(res,dp(c-1,n1-8,n2,n3)+8);
        if(n1>=3&&n2>=1) res=min(res,dp(c-1,n1-3,n2-1,n3)+4);
        if(n1>=3&&n3>=1) res=min(res,dp(c-1,n1-3,n2+1,n3-1)+4);
        if(n2>=2) res=min(res,dp(c-1,n1+2,n2-2,n3)+2);
        if(n3>=1) res=min(res,dp(c-1,n1+2,n2,n3-1)+1);
        flag=1;return res;
    }
}


你可能感兴趣的:(c,测试,n2)