码迷,mamicode.com
首页 > 其他好文 > 详细

CSU1622: Generalized Roman Numerals(区间DP)

时间:2015-05-18 20:53:20      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:csu

Description

技术分享

Input

技术分享

Output

技术分享

Sample Input

IVX
XIXIX
0

Sample Output

Case 1: 4 6
Case 2: 8 10 28 30 32

HINT

Source



题意:给出一个罗马数字,要你输出这罗马数字所有可能组成的数
罗马数字组成规则:
1.左边的字母大于等于右边的字母,两者相加
2.左边的字母小于右边的字母,后者减去前者
3.一个罗马数字串,可以随意组合

思路:这题要用区间dp处理,dp[i][j],代表位置i之后的j个数所能组成的数字序列,使用结构体存储顺便要记录路径


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define LS 2*i
#define RS 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 25
#define MOD 19999997
#define INF 0x3f3f3f3f
#define EXP 1e-8

char s[100];
int cas = 1;

inline int getit(char c)
{
    if(c=='I') return 1;
    if(c=='V') return 5;
    if(c=='X') return 10;
    if(c=='L') return 50;
    return 100;
}

struct node
{
    void init()
    {
        MEM(hsh,-1);
        st = 0;
    }
    void set(int x)
    {
        if(hsh[x]!=-1) return;
        hsh[x] = st;//记录路径
        st = x;//记录尾指针
    }
    int st;
    int hsh[5005];
} dp[55][55];

inline void solve(node& a,node& b,node& c)//枚举所有的情况,这里使用地址符号的时间比不使用要优化很多,原因我也不是很清楚了
{
    int i,j;
    for(i = a.st; i>0; i=a.hsh[i])
    {
        for(j = b.st; j>0; j=b.hsh[j])
        {
            if(i>=j)
                c.set(i+j);
            else
                c.set(j-i);
        }
    }
}

vector<int> ans;
int main()
{
    int i,j,k,len;
    W(~scanf("%s",s))
    {
        if(s[0]=='0')
            break;
        printf("Case %d:",cas++);
        int n = strlen(s);
        UP(i,0,n-1)
        {
            dp[i][1].init();
            dp[i][1].set(getit(s[i]));
        }
        UP(len,2,n)
        {
            UP(i,0,n-len)
            {
                dp[i][len].init();
                UP(k,1,len-1)
                {
                    solve(dp[i][k],dp[i+k][len-k],dp[i][len]);
                }
            }
        }
        ans.clear();
        for(i = dp[0][n].st; i!=0; i=dp[0][n].hsh[i])
            ans.push_back(i);
        sort(ans.begin(),ans.end());
        len = ans.size();
        UP(i,0,len-1)
        printf(" %d",ans[i]);
        printf("\n");
    }
    return 0;
}


CSU1622: Generalized Roman Numerals(区间DP)

标签:csu

原文地址:http://blog.csdn.net/libin56842/article/details/45825955

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!