UVa 10118 Free Candies

来源:互联网 发布:注册域名 编辑:程序博客网 时间:2024/05/29 08:33

题目链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1059


#include <cstdio>#include <cstring>#include <algorithm>using namespace std;// record[a][b][c][d]代表第1,2,3,4堆取了a,b,c,d个糖后(位于顶部的糖果为pile[0][a+1],pile[1][b+1],pile[2][c+1], pile[3][d+1]),// 篮子里的情况是basket[a][b][c][d]时还能取的最多糖对int record[45][45][45][45];// basket[a][b][c][d]代表第1,2,3,4堆取了a,b,c,d个糖后,篮子里的糖果情况,第i位代表第i种糖数量int basket[45][45][45][45];// pile[a][x]代表第a堆的第x个糖果的种类int pile[4][45];int n;int get_max(int* now);int main(){while(scanf("%d", &n) == 1 && n != 0){// 读入情况memset(record, -1, sizeof(record));memset(basket, 0, sizeof(basket));for(int i = 1; i <= n; i++)for(int j = 0; j <= 3; j++)scanf("%d", &pile[j][i]);// 计算结果int now[4];memset(now, 0, sizeof(now));printf("%d\n", get_max(now));}return 0;}// 计算// record[a][b][c][d]代表第1,2,3,4堆取了a,b,c,d个糖后(位于顶部的糖果为pile[0][a+1],pile[1][b+1],pile[2][c+1], pile[3][d+1]),// 篮子里的情况是basket[a][b][c][d]时还能取的最多糖对int get_max(int* now){if(record[now[0]][now[1]][now[2]][now[3]] != -1)return record[now[0]][now[1]][now[2]][now[3]];// 查看篮子中的糖果情况int b = basket[now[0]][now[1]][now[2]][now[3]];int candy[21];memset(candy, 0, sizeof(candy));int sum = 0;for(int i = 1; i <= 20; i++){candy[21-i] = b - ((b >> 1) << 1);b = (b >> 1);sum += candy[21-i];}if(sum >= 5){record[now[0]][now[1]][now[2]][now[3]] = 0;return record[now[0]][now[1]][now[2]][now[3]];}// 如果篮子有空,查看四种可能的取法int ans = 0;for(int i = 0; i < 4; i++){if(now[i]+1 > n)continue;int new_c = pile[i][now[i]+1];now[i]++;if(candy[new_c] == 0){candy[new_c] = 1;int this_b = 0;for(int i = 1; i <= 20; i++)this_b = (this_b<<1) + candy[i];basket[now[0]][now[1]][now[2]][now[3]] = this_b;ans = max(ans, get_max(now));candy[new_c] = 0;}else if(candy[new_c] == 1){candy[new_c] = 0;int this_b = 0;                        for(int i = 1; i <= 20; i++)                                this_b = (this_b<<1) + candy[i];                        basket[now[0]][now[1]][now[2]][now[3]] = this_b;                        ans = max(ans, get_max(now) + 1);                           candy[new_c] = 1;}now[i]--;}record[now[0]][now[1]][now[2]][now[3]] = ans;return record[now[0]][now[1]][now[2]][now[3]];}

感觉是道好题,题目状态一开始比较好想,无非是四个堆的要取的位置和篮子里的情况,篮子里的情况可以用一个整数来二进制表示。

但是即使这样,存储的数组也太大((40^4)*(2^20)). 后来没想出来,看了别人的做法,发现如果能够达到目前堆的状态,那么篮子里的情况应该是唯一的。(不知如何证明)

所以只需要保存堆的状态就可以了,用另外一个数组来记录每个堆的状态下篮子的情况。

0 0
原创粉丝点击