【HDOJ】3828 A + B problem

本文介绍了一种基于贪心策略的字符串拼接算法,旨在寻找最优字符串组合方式以达到最短长度。通过预处理去除重复项并计算任意两字符串间的最长公共子串长度,利用动态规划方法求解。代码实现覆盖了状态转移、结果回溯等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

显然需要贪心,重叠越长越好,这样最终的串长尽可能短。
需要注意的是,不要考虑中间结果,显然是个状态dp。
先做预处理去重,然后求任意一对串的公共长度。

  1 /* 3828 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25 
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 
 44 
 45 const int INF = 0x3f3f3f3f;
 46 const int maxl = 70;
 47 const int maxn = 16;
 48 const int mod = 1000000009;
 49 __int64 a[maxn];
 50 char word[maxn][maxl];
 51 string sw[maxn];
 52 int nxt[maxl];
 53 int Len[maxn];
 54 bool visit[maxn];
 55 int dp[1<<16][16];
 56 int M[16][16];
 57 int n;
 58 
 59 void f(char *s, __int64 x) {
 60     int l = 0;
 61     while (x) {
 62         s[l] = (x & 1) + '0';
 63         ++l;
 64         x >>= 1;
 65     }
 66     s[l] = '\0';
 67     reverse(s, s+l);
 68 }
 69 
 70 void getnext(char *s) {
 71     int i = 0, j = -1;
 72     int l = strlen(s);
 73     
 74     nxt[0] = -1;
 75     while (i < l) {
 76         if (j==-1 || s[i]==s[j]) {
 77             ++i;
 78             ++j;
 79             nxt[i] = j;
 80         } else {
 81             j = nxt[j];
 82         }
 83     }
 84 }
 85 
 86 bool match(char *d, char *s, int ld, int ls) {
 87     int i = 0, j = 0;
 88     
 89     while (i < ld) {
 90         if (d[i] == s[j]) {
 91             ++i;
 92             ++j;
 93         } else {
 94             j = nxt[j];
 95             if (j == -1) {
 96                 j = 0;
 97                 ++i;
 98             }
 99         }
100         if (j == ls)
101             return true;
102     }
103     
104     return false;
105 }
106 
107 void cover() {
108     memset(visit, false, sizeof(visit));
109     rep(i, 0, n) {
110         getnext(word[i]);
111         rep(j, 0, n) {
112             if (i == j)
113                 continue;
114             if (match(word[j], word[i], Len[j], Len[i])) {
115                 visit[i] = true;
116                 break;
117             }
118         }
119     }
120     
121     int nn = 0;
122     rep(i, 0, n) {
123         if (!visit[i]) {
124             strcpy(word[nn], word[i]);
125             Len[nn] = strlen(word[nn]);
126             ++nn;
127         }
128     }
129     n = nn;
130 }
131 
132 bool judge(int l, char *sa, char *sb) {
133     rep(i, 0, l) {
134         if (sa[i] != sb[i])
135             return false;
136     }
137     return true;
138 }
139 
140 int LongFix(int a, int b) {
141     per(l, 1, Len[a]) {
142         if (Len[b]>=l && judge(l, word[a]+Len[a]-l, word[b]))
143             return l;
144     }
145 
146     return 0;
147 }
148 
149 void calc() {
150     rep(i, 0, n) {
151         rep(j, 0, n) {
152             if (i == j) {
153                 M[i][j] = Len[i];
154                 continue;
155             }
156             M[i][j] = LongFix(i, j);
157         }
158     }
159 }
160 
161 void solve() {
162     sort(a, a+n);
163     n = unique(a, a+n) - a;
164     rep(i, 0, n) {
165         f(word[i], a[i]);
166         Len[i] = strlen(word[i]);
167     }
168     cover();
169     calc();
170     
171     int mst = 1 << n;
172     
173     memset(dp, INF, sizeof(dp));
174     rep(i, 0, n)
175         dp[1<<i][i] = Len[i];
176         
177     rep(i, 0, mst) {
178         rep(j, 0, n) {
179             if (dp[i][j]==INF || (i&(1<<j))==0)
180                 continue;
181             
182             rep(k, 0, n) {
183                 if (i & (1<<k))
184                     continue;
185                 
186                 int nst = i | (1<<k);
187                 dp[nst][k] = min(dp[nst][k], dp[i][j]+Len[k]-M[k][j]);
188             }
189         }
190     }
191     
192     rep(i, 0, n)
193         sw[i] = string(word[i]);
194         
195     int st = mst - 1;
196     int p = -1;
197     
198     string str = "";
199     while (1) {
200         int mn = INF, v;
201         string tstr, mnstr;
202         
203         rep(i, 0, n) {
204             if ((st & (1<<i)) == 0)
205                 continue;
206             
207             int tmp = dp[st][i];
208             if (p >= 0) {
209                 tmp -= M[p][i];
210                 tstr = sw[i].substr(M[p][i]);
211             } else {
212                 tstr = sw[i];
213             }
214             
215             if (tmp<mn || (tmp==mn && tstr<mnstr)) {
216                 mn = tmp;
217                 mnstr = tstr;
218                 v = i;
219             }
220         }
221         
222         str += mnstr;
223         p = v;
224         st ^= (1 << v);
225         if (st == 0)
226             break;
227     }
228     
229     int length = str.length(), base = 1;
230     __int64 ans = 0;
231     
232     per(i, 0, length) {
233         if (str[i] == '1')
234             ans = (ans + base) % mod;
235         base = (base + base) % mod;
236     }
237     
238     printf("%I64d\n", ans);
239 }
240 
241 int main() {
242     ios::sync_with_stdio(false);
243     #ifndef ONLINE_JUDGE
244         freopen("data.in", "r", stdin);
245         freopen("data.out", "w", stdout);
246     #endif
247     
248     while (cin >> n) {
249         rep(i, 0, n)
250             cin >> a[i];
251         solve();
252     }
253     
254     #ifndef ONLINE_JUDGE
255         printf("time = %d.\n", (int)clock());
256     #endif
257     
258     return 0;
259 }

 

转载于:https://www.cnblogs.com/bombe1013/p/5156063.html

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值