UVALive 6904 Travel Card dp

题意:

有八种买票的规则 问你最省钱的买票方式

 

思路:

首先就是正常的状态转移

包天的票转移到一天前 包周的转移到一周前 包月的到一个月之前

不好想的是

如果我已经买了单独bus的票 我可能购买小规格的两个都用的票

可能买单独一天或者单独一周的

 

 1 #include<bits/stdc++.h>
 2 #define cl(a,b) memset(a,b,sizeof(a))
 3 #define debug(a) cerr<<#a<<"=="<<a<<endl
 4 using namespace std;
 5 typedef long long ll;
 6 typedef pair<int,int> pii;
 7 
 8 const int maxn=1e4+100;
 9 
10 int vis[50];
11 int dp[maxn];
12 pii day[maxn];
13 pii cnt[maxn];
14 
15 void init()
16 {
17     cl(dp,0);
18     cl(day,0);
19     cl(cnt,0);
20 }
21 
22 int train(int st,int d)
23 {
24     int ed=st+d-1;
25     cl(vis,0);
26     for(int i=ed;i>=st;i--)
27     {
28         int now=i-st;
29         vis[now]=vis[now+1]+day[i].second*2;
30         vis[now]=min(vis[now],vis[now+1]+6);
31         if(d>=30) vis[now]=min(vis[now],vis[now+7]+36);
32     }
33     return vis[0];
34 }
35 
36 int main()
37 {
38     int T;
39     scanf("%d",&T);
40     while(T--)
41     {
42         int n;
43         init();
44         scanf("%d",&n);
45         for(int i=1; i<=n; i++)
46         {
47             scanf("%d%d",&day[i].first,&day[i].second);
48             dp[i]=(day[i].first)+(day[i].second*2);
49         }
50         for(int i=n; i>=1; i--)
51         {
52             dp[i]+=dp[i+1];
53             dp[i]=min(dp[i],dp[i+1]+min(3+day[i].second*2,6));
54             dp[i]=min(dp[i],dp[i+7]+min(18+train(i,7),36));
55             dp[i]=min(dp[i],dp[i+30]+min(45+train(i,30),90));
56         }
57         printf("%d\n",dp[1]);
58     }
59     return 0;
60 }/*
61 
62 2
63 3
64 1 0
65 5 0
66 0 2
67 6
68 2 3
69 4 2
70 1 5
71 2 2
72 3 4
73 5 5
74 
75 */

 

posted @ 2017-09-20 23:19  良将ℓ  阅读(136)  评论(0编辑  收藏  举报