题意:
有八种买票的规则 问你最省钱的买票方式
思路:
首先就是正常的状态转移
包天的票转移到一天前 包周的转移到一周前 包月的到一个月之前
不好想的是
如果我已经买了单独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 ",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 */